Skip to content
Second Brain Chronicles
Go back

Three Permission Layers, Zero Files Imported

Three Permission Layers, Zero Files Imported

Three errors. Two container recreations. Each error invisible until the one above it was peeled away.

I had two Splatoon manga volumes — CBZ files, already tagged and ready — and I wanted them on the shelf in Booklore. The whole point of BookDrop is that you don’t think about it. You drag files into a folder. The app notices, imports them, sorts them by series and volume number. Thirty seconds, maybe. I’d done it with local storage dozens of times without incident.

These files were landing on a NAS-mounted CIFS share. That shouldn’t matter. A volume is a volume is a volume. I dropped the files in, waited, and watched nothing happen. The logs told me why — or rather, they told me the first of three whys.

What I expected: Drag two files into BookDrop. Auto-import picks them up, shelves them. Done in thirty seconds.

What actually happened: Three sequential permission failures, each invisible until the one above it was fixed. An hour of container lifecycle management for a drag-and-drop operation.

Layer 1: The Obvious One

Read-only file system

Fair enough. The nas_comics volume was mounted with :ro in docker-compose. I’d originally set it read-only because Booklore was just reading and indexing — it didn’t need to write. BookDrop changes the deal. Auto-import means moving files from the drop folder into the library structure. Writing is the whole point.

volumes:
  - /mnt/nas/comics:/comics:ro
  - /mnt/nas/comics:/comics

Removed :ro. Recreated the container. Dropped the files in again.

Fixed. Tested. Broke again.

That felt premature. It was.

Layer 2: The UID Mismatch

Access Denied

Different error. Progress? Maybe. The kind of progress where the mountain doesn’t get shorter, it just changes color.

Booklore’s Java process runs as uid=501(booklore). The CIFS mount is owned by uid=1000 with 755 permissions. The container user literally cannot write to a directory owned by a different user with no group or world write permissions.

This is one of Docker’s most common traps and it’s invisible when a read-only flag is sitting on top of it. The :ro mount was absorbing all the write failures. Remove the obvious restriction and the subtle one appears. I couldn’t have found this bug without fixing the first one — which makes the first fix feel useful and the second fix feel like the real answer.

driver_opts:
  type: cifs
  device: "//nas/comics"
  o: "username=...,password=...,file_mode=0777,dir_mode=0777"

Setting 0777 on a CIFS mount feels wrong — it’s not actually changing filesystem permissions on the NAS, it’s telling the mount driver to present everything as world-writable to the container. The NAS still has its own ACLs. But it’s the standard fix for the UID mismatch problem with CIFS volumes in Docker.

This required removing the volume entirely and recreating it. Docker doesn’t let you change volume options on an existing named volume. So: docker-compose down, docker volume rm, edit the compose file, docker-compose up -d. Container recreation number two.

Dropped the files in. Waited. Got that little hit of confidence that comes from having already been wrong once and surely not being wrong again.

Fixed. Tested. Broke again.

Layer 3: The Upstream Bug

Operation not permitted

Third error. Third personality. At this point I’m not even surprised. I’m just reading the next page.

Booklore’s auto-naming generates directory paths from manga metadata — series name, volume number, reading order. For manga, this produces paths like 06. Splatoon/ with a trailing dot and space. Perfectly legal on ext4. Illegal on SMB shares.

The CIFS filesystem itself was refusing to create the directories Booklore wanted to create. Not a permission problem. Not a configuration problem. A genuine incompatibility between Booklore’s naming logic and network storage path restrictions.

LayerErrorCauseWhat It Hid
1Read-only file system:ro mount flagUID mismatch (Layer 2)
2Access DeniedContainer UID ≠ mount UIDSMB path bug (Layer 3)
3Operation not permittedIllegal characters in SMB pathsNothing — this was the bottom

No configuration fix for layer three. I manually placed the files with clean filenames and moved on. This is a Booklore bug — their auto-naming generates filenames that are illegal on network storage. Anyone running comics on a NAS will hit it eventually.

The Psychology of Layered Bugs

The temptation after fixing layer one is to drop the file in, see it work, and walk away. That’s exactly what I did — twice. Each fix felt like the fix. The read-only flag was obvious. The UID mismatch was a known Docker pattern. Each one produced a satisfying moment of “ah, that was it” followed by the same two files sitting in BookDrop, unprocessed.

Why layered permission bugs are particularly deceptive

Permission layers evaluate in order. First “no” wins. Every “no” after that is silent — it never gets reached. So you fix one thing, it works, you feel smart, and then it breaks for a completely different reason you couldn’t have seen until the first one was cleared.

The total number of layers is unknown until you’ve peeled them all. Each fix creates false confidence that scales with the number already fixed. The countermeasure is asking “what else could say no?” after every fix, not just “does it work now?”

The Damage Report

MetricValue
Expected time~30 seconds
Actual time~1 hour
Container recreations2
Full down → volume rm → edit → up cycles2
Distinct error messages3
Layers that were fixable via configuration2 of 3
Files successfully auto-imported0

Two CBZ files. Zero of them made it in through the intended workflow. The final resolution was manual placement with hand-cleaned filenames — the thing BookDrop exists to eliminate.

Pattern Recognition

The pattern isn’t Docker-specific. It’s every system where multiple gatekeepers evaluate in sequence and only the first rejection is visible:

The structure is always the same: fix, false confidence, repeat. The fix for layer one is never the fix for the problem — it’s the fix for the first problem. Layers two and three are patient.


Share this post on:

Previous Post
238 Apple Books Into Booklore Via a Categorisation Script
Next Post
My iPad Wiped 25,743 Files in Two Minutes