kubernetes PodSecurityPolicy set to runAsNonRoot, container has runAsNonRoot and image has non-numeric user appuser, cannot verify user is non-root
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
This Kubernetes error appears when policy requires non-root execution, but Kubernetes cannot prove that the container image user is non-root because it is defined as a name such as appuser instead of a numeric UID. Even if your Dockerfile uses a non-root username, policy admission checks often need explicit numeric identity. The fix is to align image user configuration and pod security context with numeric values.
Why Kubernetes Rejects the Pod
With runAsNonRoot: true, admission logic verifies that container user is not root. If image metadata contains USER appuser, Kubernetes cannot always resolve that name during admission because user lookup depends on image filesystem and runtime context.
As a result, Kubernetes returns an error similar to:
- image has non-numeric user
- cannot verify user is non-root
The policy is protecting you from ambiguous user identity.
Understand the Policy Check Path
Admission checks typically evaluate:
- pod or container
securityContext.runAsNonRoot - optional
runAsUsernumeric UID - image
USERfield if no explicit UID is provided
If no numeric UID is available at policy time, verification can fail even for images that actually run as non-root.
Reliable Fix: Use Numeric UID in Image and Pod Spec
Dockerfile example
Using USER 10001 gives Kubernetes a verifiable numeric non-root user.
Pod specification example
This removes ambiguity and satisfies strict non-root checks.
If You Only Control Pod Spec and Not Image
Sometimes you cannot rebuild third-party images. You may still run with explicit runAsUser if image supports that UID and required file permissions.
Checklist before forcing UID:
- verify app files are readable and writable as chosen UID
- verify entrypoint does not require root startup actions
- verify mounted volumes are accessible with that UID and
fsGroup
If the image assumes root-only paths, forced UID may cause runtime errors even after admission succeeds.
PodSecurityPolicy Deprecation Context
PodSecurityPolicy is removed in newer Kubernetes versions, but similar non-root requirements exist via Pod Security Admission and policy engines such as OPA Gatekeeper or Kyverno. The same numeric UID principle still applies.
So even if your cluster no longer uses PSP objects, this error class can still appear through equivalent security policies.
Debugging Workflow
When this issue appears, use a focused sequence:
- inspect image user metadata
- inspect pod and container security contexts
- confirm policy mode and constraints
- test with explicit numeric
runAsUser - validate container filesystem permissions for that UID
Image inspection example:
If output is a username rather than numeric UID, update image or pod configuration.
Security Hardening Around Non-Root
Running as non-root is necessary but not sufficient. Combine with:
- '
allowPrivilegeEscalation: false' - dropped Linux capabilities
- read-only root filesystem where possible
- seccomp profile and apparmor where supported
These controls reduce exploit impact beyond user identity enforcement.
Migration Strategy for Existing Images
For legacy images with named users:
- rebuild image with fixed numeric UID and GID
- align file ownership during build
- set explicit securityContext in manifests
- roll out in staging and validate file and volume access
- enforce policy gate in CI to block root or ambiguous users
This creates repeatable compliance for new deployments.
Common Pitfalls
- Assuming username in Dockerfile is enough for admission verification.
- Setting
runAsNonRootwithoutrunAsUserwhen image user is non-numeric. - Forcing UID in pod spec without validating filesystem ownership.
- Treating PSP deprecation as removal of non-root requirements.
- Passing admission checks but leaving privilege escalation settings insecure.
Summary
- The error happens because Kubernetes cannot verify non-root identity from named image users.
- Numeric UID is the most reliable fix for policy enforcement.
- Set both image
USERand podrunAsUserto explicit non-root values. - Validate runtime permissions after identity changes.
- Apply additional hardening controls so non-root execution is part of a complete security posture.

