Skip to content
Commitpedia
Log in Join & edit

Fix: Permission denied in a container on OpenShift because of the random UID

A container that works under Docker or Kubernetes crashes on OpenShift with permission denied, because restricted-v2 runs it with a random non-root UID. Fix the image, use a volume, or grant an SCC.

Not checked by a trusted editor yet Last edited Outdated?

Edit history of Fix: Permission denied in a container on OpenShift because of the random UID: 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
3 min

A typical example is the official nginx image, which crashes with lines like these in oc logs:

[warn] 1#1: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
[emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

Other images fail the same way with their own wording: a database that cannot write its data directory, an app that cannot create a cache or PID file, or a server that cannot bind to port 80. The pod goes into CrashLoopBackOff.

Why it happens

Under the default restricted-v2 SCC, OpenShift ignores the image’s USER and runs the container with a UID from the project’s range, a large number such as 1000680000. That user is a member of the root group (GID 0) but owns nothing in the image. Directories created for root or for a fixed user like nginx are not writable for it, and ports below 1024 cannot be bound.

Confirm the cause

oc logs deploy/web --previous
oc get pod POD -o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'
oc debug deploy/web -- id
oc debug deploy/web -- ls -ld /var/cache/nginx

oc debug starts a copy of the pod with the same security settings, so it works even when the real container crashes immediately. If id shows something like uid=1000680000 gid=0(root) and the directory belongs to another user without group write permission, this is your problem.

Fix 1 (best): use an image that supports arbitrary UIDs

Many projects publish a non-root or “unprivileged” variant of their image, and images made for OpenShift are built to run with any UID. Check the image’s documentation, then switch the deployment:

oc set image deployment/web web=registry.example.com/team/web-nonroot:1.0

Fix 2: make your own image group-writable

This is the approach from the OpenShift image guidelines: hand every path the process writes to over to the root group, give the group the same permissions as the owner, and listen on a port above 1024. In this example the base image’s server is configured to use the /var/cache/app, /var/run/app and /var/log/app paths; for nginx that means its cache, PID file and log paths, and a listen 8080 directive instead of port 80.

FROM registry.example.com/base/web-server:2.4
USER 0
RUN mkdir -p /var/cache/app /var/run/app /var/log/app && \
    chgrp -R 0 /var/cache/app /var/run/app /var/log/app /etc/app && \
    chmod -R g=u /var/cache/app /var/run/app /var/log/app /etc/app
USER 1001
EXPOSE 8080

Rebuild, push, update the deployment and change the Service and Route to port 8080. Do not make /etc/passwd writable; the documentation explicitly says that is not needed.

Fix 3: put writable paths on a volume

If you cannot change the image, mount an emptyDir over the directories it writes to. A fresh emptyDir is writable for the pod’s user.

oc set volume deployment/web --add --name=cache --type=emptyDir --mount-path=/var/cache/nginx

For persistent volumes, the pod’s fsGroup from the project range normally makes the volume group-writable. If an older volume was filled by a different user, its files may need their ownership fixed once.

Fix 4 (last resort): grant a more permissive SCC

If the software truly must run as a fixed user or as root, a cluster administrator can let a dedicated service account use nonroot-v2 (fixed non-root UID) or anyuid (any UID including 0). This weakens the isolation OpenShift gives you, so keep it limited to that one workload and never edit the default SCCs.

oc create serviceaccount web-sa
oc adm policy add-scc-to-user anyuid -z web-sa
oc set serviceaccount deployment/web web-sa
oc get pods
oc get pod POD -o jsonpath='{.metadata.annotations.openshift\.io/scc}{"\n"}'

The image must also really request that user (a USER line or runAsUser in the pod spec); with anyuid and no request, it runs as the image’s user.

Official documentation

See also

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Commitpedia +4,147 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?