A rootless worker writes into a bind-mounted host directory, and the new files show a high, unowned id - why?
answer
- ids shift by a fixed offset
- inside zero is the base of the block
- the kernel records the mapped id
- no host account claims that number
- the other direction refuses inside-root
basics
~20 sUnder id remapping the container's ids sit on a range of unprivileged host ids, so a file created inside as id 0 lands on the host owned by the first id of that range - a number no host account claims, which is why tools print it raw.
solid answer
~50 sId remapping gives the container a contiguous block of unprivileged host ids and translates every id across the boundary: inside `0` becomes the base of that block, inside `1` the next one, and so on. When the worker writes into a directory that is really the host's filesystem seen through the boundary, the file is created with the mapped host id, not the number the process reported. Nothing on the host is registered under that number, so listings show the digits instead of a name. The same translation runs in the other direction: an existing host file owned by the operator's own id sits outside the container's block, so the worker sees it as an unmapped id and is refused, even though it reports as root. Both symptoms are one mechanism read from two sides.
code
pseudocode · 17 linesid map for this container:
inside 0 -> host 100000
inside 1..65535 -> host 100001..165535
# direction 1: a write from inside
worker identity inside = 0
worker writes /data/report.txt # /data is a host directory mounted in
kernel records owner = 100000 # the mapped id, not the reported 0
host listing shows: report.txt owner 100000 group 100000
# direction 2: a read of a file the host already had
host file /srv/queue/incoming owner 1000, readable by its owner only
worker (inside 0, host 100000) opens it
kernel compares 100000 with 1000 -> not the owner -> refused
# note: host id 1000 is outside 100000..165535,
# so inside the container it has no mapped id at allgo deeper
Recognise the symptom and its cause: a high nameless owner on the host is the inside id plus a fixed offset, not damage. Do not go looking for a corrupted filesystem.
Explain both directions from one mechanism - writes recorded under the mapped id, and host files whose owner falls outside the block being unreachable - and why the kernel cannot trust the reported inside id.
Diagnose without guessing: compare the file's host owner against the container's mapped block before touching privileges, and choose a fix that does not widen access for every other workload on the host.
The judgment you own is whether host directories shared with containers belong in your platform's contract at all, given that the mapping negotiation has to be re-done by every team that uses one.
## Where the strange number comes from Id remapping gives a container a contiguous block of host ids - typically a large block of high, otherwise unused numbers - and translates ids in both directions at the boundary. Inside id `0` is the base of the block; inside `1` is the next one; the whole range shifts by a fixed offset. So when the queue consumer, running as id 0 inside, creates a file on a host directory mounted into it, the kernel records the **mapped** host id as the owner, because that is the id the process really carries on the host. The number is not a corruption and not a bug: it is the inside id plus the offset. Nothing on the host is registered under it, so a directory listing has no name to print and shows the digits. This is also why the numbers look arbitrary but are not. A file created inside by a service account with inside id 1000 shows up as base plus 1000. If you know the base, you can read the ownership backwards and tell exactly which inside identity wrote the file. ## The same mechanism, read from both sides | Direction | What you do | What you see | Why | |---|---|---|---| | Writing out | Worker (inside 0) creates a file on a mounted host directory | Host shows a high, nameless owner id | The kernel records the mapped host id, not the reported inside id | | Reading in | Worker (inside 0) opens an existing host file owned by the operator | Refused, though the process reports as root | The operator's host id is outside the container's block, so inside it is an unmapped foreign id | The second row is the one that surprises people, because it looks like root being refused. It is not: the process is root over the container's view, and the file's owner is not in that view at all. Many setups render such an owner as a single catch-all unmapped id, which is why the file appears to belong to nobody in particular - and why no amount of changing the process's inside identity fixes it. ## Why the kernel cannot simply trust the inside number If the inside number were taken at face value, the entire point of remapping would collapse. Any unprivileged operator could start a container, declare itself id 0 inside, write through a mounted path and own host files as root. The translation is not a cosmetic inconvenience on top of the boundary - it **is** the boundary for file ownership. Every awkward symptom in this section is the mechanism working. That also explains a related trap. Changing a file's ownership from inside the container changes it to an inside id, which maps to another id in the same block. It can never set a host id outside the block, because the process has no authority over ids it is not mapped to. A workload cannot chown its way out of the mapping. ## Making a shared host directory actually work There is no single fix, but there is a short list of honest ones: - **Make the directory's ownership match a mapped id.** Set the host directory to the mapped equivalent of the inside id the workload runs as, so both sides agree. - **Use a group both sides can see.** Give the directory a group whose host id falls inside the mapped block, and run the workload under the corresponding inside group. - **Align the mapping deliberately.** Some setups map one chosen inside id onto one chosen host id so a specific account matches across the boundary, rather than shifting the whole block blindly. - **Stop sharing the directory.** If nothing on the host needs to read those files, a storage location the platform provisions and tracks for the container avoids the negotiation entirely - that is a separate decision about where the data should live. - **Do not paper over it with a wide-open mode.** Making the directory writable by everyone does make the symptom go away, and it hands every other workload on that host the same access. ## Reading the symptom quickly 1. If host listings show high nameless ids on files a container created, remapping is on and you are seeing the offset. That is expected; decide whether the host needs to read those files at all. 2. If a process that reports as root is refused on an existing host file, compare the file's host owner with the container's mapped block before touching privileges. This is an id problem, and granting a privilege will not fix it. 3. If the same workload behaves differently on two hosts, check whether one of them remaps ids and the other does not. That single difference changes who owns everything the workload writes through a mounted path.
- Why can the worker not just change the file's ownership from inside the container?Changing ownership from inside sets an inside id, which the mapping turns into another id in the same block. The process has no authority over host ids outside its block, so it can never assign one. The ownership has to be arranged on the host side, or the mapping aligned so the two agree.
- The same image writes files owned by root on one host and by a high id on another. What differs?One host runs the container with id remapping and the other does not. Without remapping, inside `0` is the host's root account and the files are owned by host root; with remapping, inside `0` is the base of an unprivileged block. Nothing about the image or the workload changed.
- Why does an existing host file sometimes show up inside the container as a single catch-all id?Its host owner is outside the container's mapped block, so there is no inside id that corresponds to it. Rather than fail the listing, many setups render every unmapped owner as one designated placeholder id, which is why several unrelated files can appear to share an owner that no account uses.
saying these in an interview costs you the question
- Calls the high owner id filesystem corruption rather than a mapped id
- Thinks changing ownership from inside can set a host id outside the block
- Expects a process reporting as root to read any host file mounted in
- Believes the mapping applies to writes but not to reads
- Fixes it by making the shared host directory writable by everyone
- Assumes the offset is random rather than a fixed block base