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?
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
- 0157 oc cheat sheet: everyday OpenShift CLI commands The oc commands you use every day, grouped by task: login and projects, apps and builds, routes, config, debugging, permissions and admin… Intermediate · Reference · Any system Article Deploying applications · Troubleshooting 15 Oct 2026
- 0158 Collect an OpenShift project report with oc A read-only bash script that gathers a project's workloads, pods, routes, builds, storage and warning events, plus describe output and logs of… Intermediate · How-to · Linux, macOS Script Deploying applications · Troubleshooting 15 Oct 2026
- 0159 OpenShift cluster health snapshot: oc adm, nodes, MachineConfigPools and updates An admin overview of OpenShift day-2 checks (cluster version, update channels, cluster Operators, nodes, MachineConfigPools, must-gather) with a read-only bash script that… Advanced · Reference · Linux, macOS Script Cluster administration · Troubleshooting 15 Oct 2026
- 0161 Fix: Error from server (Forbidden): … is forbidden: User … cannot … in OpenShift oc refuses a command with Error from server (Forbidden). The message names the user, verb, resource and project. Learn how to read… Intermediate · Fix · Any system Article Cluster administration · Troubleshooting 15 Oct 2026
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Commitpedia +4,147 chars