Kubernetes Error Guide: 'violates PodSecurity restricted' — Fix Admission Rejections
Fix the 'violates PodSecurity restricted' admission error in Kubernetes: satisfy the restricted standard's securityContext, capabilities, and seccomp rules.
- #kubernetes
- #troubleshooting
- #errors
- #security
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
Your pod (or its controller) is rejected at admission because it does not meet the Pod Security Standard enforced on the namespace. Pod Security admission is a built-in controller that evaluates every pod against one of three levels — privileged, baseline, or restricted — based on labels on the namespace. When the level is restricted and your pod is missing the required hardening, the API server refuses to create it and lists exactly which fields are wrong.
The literal error looks like this:
Error from server (Forbidden): error when creating "pod.yaml": pods "api" is forbidden:
violates PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "api" must set
securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "api" must set
securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true, seccompProfile (pod or container
must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
Unlike a runtime failure, this happens at creation time — the object is never stored. For a Deployment/StatefulSet the Deployment is created but pods are not, and the failure shows up as a FailedCreate event on the ReplicaSet. The fix is to add the specific securityContext settings the message names.
Symptoms
kubectl applyreturnsForbidden ... violates PodSecurity "restricted:latest"with a list of violations.- A Deployment exists but has zero pods;
kubectl describe rsshowsFailedCreate. - The namespace carries
pod-security.kubernetes.io/enforce=restricted. - Each violation names the exact field to set.
kubectl apply -f pod.yaml
Error from server (Forbidden): pods "api" is forbidden: violates PodSecurity "restricted:latest":
allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
Common Root Causes
1. Missing allowPrivilegeEscalation=false
restricted requires every container to explicitly set allowPrivilegeEscalation: false. Omitting it (even though the default is often false at runtime) is a violation because admission requires it to be explicit.
allowPrivilegeEscalation != false (container "api" must set securityContext.allowPrivilegeEscalation=false)
2. Capabilities not dropped to ALL
Containers must drop: ["ALL"] and may only add back NET_BIND_SERVICE. Any container without an explicit drop-all is rejected.
unrestricted capabilities (container "api" must set securityContext.capabilities.drop=["ALL"])
3. runAsNonRoot not set to true
restricted requires runAsNonRoot: true at the pod or container level.
runAsNonRoot != true (pod or container "api" must set securityContext.runAsNonRoot=true)
4. Missing seccompProfile
The pod or each container must set seccompProfile.type to RuntimeDefault or Localhost.
seccompProfile (pod or container must set securityContext.seccompProfile.type to "RuntimeDefault")
5. Host namespaces, hostPath, or privileged set
Using hostNetwork, hostPID, hostPath volumes, or privileged: true violates restricted (and baseline for privileged) and cannot be waved through without lowering the level.
Diagnostic Workflow
Step 1: Read every violation in the message
kubectl apply -f pod.yaml
Pod Security lists all failing fields at once — fix them together rather than one at a time.
Step 2: Confirm the enforced level
kubectl get ns <NS> -o jsonpath='{.metadata.labels}'
{"pod-security.kubernetes.io/enforce":"restricted","pod-security.kubernetes.io/enforce-version":"latest"}
Step 3: Dry-run to preview violations for a controller
For Deployments where pods fail silently, use the warn behavior or a server dry-run:
kubectl apply -f deployment.yaml --dry-run=server
kubectl describe rs -l app=<APP> | grep -A3 FailedCreate
Step 4: Apply the compliant securityContext
Add pod- and container-level settings covering all four common requirements, then re-apply.
Step 5: Verify pods are created
kubectl get pods -l app=<APP>
kubectl get events -n <NS> --sort-by='.lastTimestamp' | grep -i podsecurity
Example Root Cause Analysis
A team deploys a Deployment into a hardened namespace and sees the workload with no pods:
kubectl get deploy,rs,pods -l app=api
deployment.apps/api 0/2 0 0 30s
replicaset.apps/api-6c9d 2 0 0 30s
The ReplicaSet cannot create pods:
kubectl describe rs api-6c9d | grep -A3 FailedCreate
Warning FailedCreate ... pods "api-6c9d-" is forbidden: violates PodSecurity "restricted:latest":
allowPrivilegeEscalation != false, unrestricted capabilities, runAsNonRoot != true, seccompProfile
The namespace enforces restricted, and the pod template has no securityContext. Adding the required fields makes it compliant:
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: api
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
kubectl apply -f deployment.yaml
kubectl rollout status deployment api
The ReplicaSet now creates pods and the Deployment reaches 2/2.
Prevention Best Practices
- Bake a
restricted-compliant securityContext into every workload template so admission never blocks a deploy. - Label namespaces with
warnandauditin addition toenforceso violations surface as warnings in lower environments before they block production. - Set pod-level
runAsNonRoot,seccompProfile, andfsGrouponce, and container-levelallowPrivilegeEscalation: false+capabilities.drop: ["ALL"]on each container. - Validate manifests in CI with a policy check (or
kubectl --dry-run=server) so violations are caught pre-merge. - Reserve
privileged/baselinenamespaces for the few workloads that genuinely need host access, and keep everything elserestricted. See more in Kubernetes & Helm guides.
Quick Command Reference
# See the full list of violations
kubectl apply -f pod.yaml
# Confirm the enforced level
kubectl get ns <NS> -o jsonpath='{.metadata.labels}'
# Preview violations for a controller
kubectl apply -f deployment.yaml --dry-run=server
kubectl describe rs -l app=<APP> | grep -A3 FailedCreate
# Check PodSecurity events
kubectl get events -n <NS> --sort-by='.lastTimestamp' | grep -i podsecurity
# Verify pods after the fix
kubectl get pods -l app=<APP>
Conclusion
violates PodSecurity "restricted:latest" means Pod Security admission rejected the pod for missing the restricted standard’s hardening. The usual causes:
allowPrivilegeEscalationnot explicitly false.- Capabilities not dropped to
ALL. runAsNonRootnot true.- Missing
seccompProfile. - Host namespaces,
hostPath, orprivilegedin use.
Read every violation the message lists and add the corresponding securityContext fields together. For workloads behind a controller, check the ReplicaSet’s FailedCreate event. For ad-hoc triage, the free incident assistant can turn a PodSecurity rejection into a compliant securityContext block.
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.