Podman Error: 'potentially insufficient UIDs or GIDs available in user namespace' on Rootless Pulls
Fix Podman's insufficient UIDs error: inspect the mapping with podman unshare, widen /etc/subuid and /etc/subgid to 65536, run podman system migrate, or use --uidmap and --userns=keep-id.
- #podman
- #containers
- #troubleshooting
- #errors
Stuck on this Podman error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Exact Error Message
$ podman pull docker.io/library/postgres:16
Copying blob sha256:9f13f5a53d11 done
Error: writing blob: adding layer with blob "sha256:9f13f5a53d11":
processing tar file(archive/tar: invalid tar header): potentially insufficient UIDs or GIDs
available in user namespace (requested 0:42 for /etc/gshadow): Check /etc/subuid and /etc/subgid:
lchown /etc/gshadow: invalid argument
The same condition can appear at run time when a volume or image path is chowned:
Error: unable to start container: copying of /var/lib/app: potentially insufficient UIDs or GIDs
available in user namespace (requested 100999:100999 for /var/lib/app): Check /etc/subuid and /etc/subgid
What It Means
Rootless Podman maps your host user to UID 0 inside a user namespace and maps a block of subordinate IDs — the range granted in /etc/subuid and /etc/subgid — to the remaining container UIDs. When Podman unpacks an image layer it must reproduce each file’s ownership inside that namespace. If a file in the image is owned by a UID that falls outside the mapped range, there is no host UID to translate it to, and the lchown fails with invalid argument. Podman catches this and rewrites the raw kernel error into the friendlier “potentially insufficient UIDs or GIDs” message.
This is a mapping-size problem, not a permissions problem. The usual triggers are an image that ships files owned by a high UID (some vendor images use IDs in the 100000+ range), a user whose subordinate range was hand-written as something small like 1000 or 10000 instead of the conventional 65536, or a range that exists but was never picked up because storage was created under an older mapping. The distinguishing detail is the requested N:M pair in the message: compare it against the size of your mapping and the arithmetic usually resolves itself immediately.
Common Causes
- The
/etc/subuidand/etc/subgidrange for the user is smaller than 65536, so common image UIDs fall outside it. - The image contains files owned by a UID higher than the mapped range — vendor images and some CI base images do this deliberately.
- The user has a range in
/etc/subuidbut not in/etc/subgid(or vice versa), so group ownership cannot be mapped. - The range was widened but
podman system migratewas never run, so~/.local/share/containers/storagestill uses the old mapping. - A custom
--uidmap/--gidmapon the command line maps fewer IDs than the image needs. --userns=keep-idis in use, which maps your own UID plus a narrow band and leaves less room for high in-image IDs.
Diagnostic Commands
Print the exact mapping currently in effect inside the namespace. The three columns are container-ID, host-ID, and count:
podman unshare cat /proc/self/uid_map
podman unshare cat /proc/self/gid_map
Compare that with what the shadow files authorize:
grep "^$(id -un):" /etc/subuid /etc/subgid
Ask Podman for its view of the mappings, which is useful when a remote or systemd context differs from your shell:
podman info --format '{{ .Host.IDMappings }}'
Find the highest UID actually used inside the offending image by unpacking it in the namespace:
podman unshare bash -c 'mnt=$(podman image mount docker.io/library/postgres:16); \
find "$mnt" -printf "%U\n" | sort -n | tail -1; podman image unmount docker.io/library/postgres:16'
Check the ownership of a host directory you are trying to bind-mount:
stat -c '%u:%g %n' /var/lib/app
Step-by-Step Resolution
-
Read the
requested N:Mnumbers out of the error and compare them to thecountcolumn from/proc/self/uid_map. If the requested UID is greater than or equal to the count, the range is simply too small. -
Widen the range to the conventional 65536 IDs.
usermodpicks a non-overlapping block, which is safer than editing by hand:
sudo usermod --add-subuids 200000-265535 --add-subgids 200000-265535 deployuser
- If an entry already exists but is too small, edit both files so the two ranges match exactly. A mismatch between subuid and subgid produces the same error on group ownership only:
# /etc/subuid and /etc/subgid — both must contain:
deployuser:200000:65536
- Re-create the rootless storage against the new mapping. Without this step the change has no effect on existing images and containers:
podman system migrate
podman unshare cat /proc/self/uid_map
If the account has nothing worth preserving, a reset is cleaner and removes any half-extracted layers left by the failed pull:
podman system reset
- For a one-off image that needs an unusually wide mapping, pass an explicit map instead of changing host configuration. This maps container UIDs 0-65535 onto the first 65536 IDs of your subordinate range:
podman run --rm \
--uidmap 0:0:65536 \
--gidmap 0:0:65536 \
docker.io/library/postgres:16 id
- When the goal is simply that a bind-mounted host directory stays owned by you inside the container,
--userns=keep-idis the right tool — it maps your host UID to the same UID in the container rather than to 0:
podman run --rm \
--userns=keep-id \
-v /var/lib/app:/data:Z \
docker.io/library/alpine:latest ls -ln /data
Note that keep-id deliberately produces a narrower map, so if the image itself contains high UIDs you may need to combine it with a widened subordinate range rather than treating it as an alternative.
If the mapping fails to be created at all rather than being too small, the failure is upstream of this one — see Podman error: cannot set up namespace using newuidmap: exit status 1. Volume-mount ownership errors that mention SELinux instead of UIDs are covered in Podman error: SELinux AVC denied on volume mount.
Prevention
- Standardize on 65536 subordinate IDs per user across the fleet and provision the entries during host bootstrap.
- Keep
/etc/subuidand/etc/subgidbyte-identical for each user so group mappings never lag behind UID mappings. - Space subordinate blocks at fixed 65536 intervals starting well above any real host UID, so ranges cannot overlap.
- Run
podman system migrateas a mandatory follow-up whenever a range changes, and encode it in the configuration-management task. - Audit base images for files owned by very high UIDs before adopting them, and prefer images that use IDs under 65536.
- Add a smoke test that pulls and runs a representative image as the rootless service account on every new host.
Related Errors
cannot set up namespace using newuidmap: exit status 1— the mapping could not be created at all, usually a missing/etc/subuidentry or setuid bit.lchown ... : invalid argument— the raw kernel error underneath this message, seen when Podman does not wrap it.Error: max user namespaces exceeded— the kernel limit on namespaces, unrelated to range size; see Podman error: max user namespaces exceeded.Error: lsetxattr operation not supported— the storage filesystem cannot hold the extended attributes a layer needs, a driver problem rather than an ID one.
Frequently Asked Questions
Why does the same image pull fine as root? Running as root uses the host’s full UID space with no namespace mapping, so any in-image UID is representable. The error is specific to rootless mode, where every file’s owner must fall inside your subordinate range.
How do I know what range I actually have? podman unshare cat /proc/self/uid_map is authoritative because it shows what the kernel installed, not what the config files say. If those two disagree, you changed /etc/subuid without running podman system migrate.
Is 65536 always enough? It covers almost every published image. If an image genuinely uses IDs above 65535, allocate a larger block for that user and re-migrate, or map that image explicitly with --uidmap. Widening beyond 65536 is uncommon and worth questioning with the image vendor first.
Does --userns=keep-id fix this? Only when the real goal was host-directory ownership rather than range size — it changes how IDs are mapped, not how many are available. For a high-UID image, widen the subordinate range as well. For more rootless container fixes, see the Podman guides.
Fixed it? Get 500 Podman & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.