Problem
A Meta LLaMA inference container is launched in a managed cloud service (Kubernetes or ECS‑style) with a persistent volume that stores model checkpoints. The container crashes during its entrypoint.sh initialization with a Permission denied error when attempting to stat or ls the mount point. As a result the model cannot be loaded and the service never becomes ready.
Typical symptom in pod logs:
2026-09-30T14:12:07.321Z ERROR: Failed to access checkpoint directory /mnt/model/checkpoint: Permission denied
Traceback (most recent call last):
File "/app/entrypoint.py", line 42, in load_checkpoint
os.listdir(CHECKPOINT_PATH)
PermissionError: [Errno 13] Permission denied: '/mnt/model/checkpoint'
2026-09-30T14:12:07.322Z INFO: Container exiting with code 1
In the orchestrator events the pod shows:
Warning FailedMount 2m45s (x3 over 5m) kubelet, node-1 MountVolume.SetUp failed for volume "model-pvc": permission denied while mounting volume
Root Cause
The failure is caused by a mismatch between the security context of the container and the file system permissions of the underlying persistent volume:
- The PVC is provisioned with a
fsGroupof1000(the default for the storage class), which results in the volume being owned byuid:1000, gid:1000. - The LLaMA container image runs as
uid:2000(non‑root) and does not belong to thefsGroup. Consequently the process has only read‑only access to the mount point. - Additionally, the
mountPathin the pod spec was set to/model/checkpointwhile the application expects/mnt/model/checkpoint. The mismatch forces the container to create a bind‑mount that inherits the original permissions, compounding the denial.
Both issues combine to produce the Permission denied error during startup.
Debug
1. Inspect pod description
kubectl describe pod llama-inference-7c9f9d6b9c-xyz
Key fields to note:
| Field | Observed Value |
|---|---|
| Security Context | runAsUser: 2000, runAsGroup: 2000 |
| fsGroup | 1000 |
| Volumes | model-pvc (PersistentVolumeClaim) |
| Volume Mounts | mountPath: /model/checkpoint |
2. Examine volume permissions on the node
ssh node-1
sudo ls -ld /var/lib/kubelet/pods/7c9f9d6b9c-xyz/volumes/kubernetes.io~csi/model-pvc
# Example output
drwxr-x--- 2 root 1000 4096 Sep 30 13:58 .
The directory is owned by root:1000 with group read/write only.
3. Verify container runtime user
kubectl exec -it llama-inference-7c9f9d6b9c-xyz -- id
uid=2000(gpuuser) gid=2000(gpuuser) groups=2000
4. Check application expected path
grep CHECKPOINT_PATH /app/entrypoint.py
# Returns: CHECKPOINT_PATH = "/mnt/model/checkpoint"
Solution
Option A – Align security context with volume group
Update the pod spec to use the same fsGroup as the storage class, allowing the container user to read/write the mounted directory.
# Before (snippet from deployment.yaml)
spec:
securityContext:
runAsUser: 2000
runAsGroup: 2000
# fsGroup omitted, defaults to storage class value (1000)
# After
spec:
securityContext:
runAsUser: 2000
runAsGroup: 2000
fsGroup: 2000 # <-- added
Setting fsGroup: 2000 causes the kubelet to chown the volume to gid=2000 before the container starts, granting the required permissions.
Option B – Run container as root (less preferred)
If changing fsGroup is not possible, modify the security context to run as root:
spec:
securityContext:
runAsUser: 0
runAsGroup: 0
Root has unrestricted access, but this bypasses the principle of least privilege.
Option C – Correct mountPath to match application expectation
Update the volumeMounts entry so the path aligns with CHECKPOINT_PATH used by the code.
# Before
volumeMounts:
- name: model-pvc
mountPath: /model/checkpoint
# After
volumeMounts:
- name: model-pvc
mountPath: /mnt/model/checkpoint
Combined recommended fix
Apply both the corrected fsGroup and the proper mountPath to eliminate permission errors and path mismatches.
Verify
- Redeploy the updated manifest:
kubectl apply -f deployment.yaml
kubectl rollout status deployment/llama-inference
Ready state:
kubectl get pod -l app=llama-inference -w
kubectl logs -f llama-inference-7c9f9d6b9c-xyz
2026-09-30T14:15:12.004Z INFO: Loading checkpoint from /mnt/model/checkpoint
2026-09-30T14:15:13.721Z INFO: Model loaded successfully, ready to serve requests
sudo ls -ld /var/lib/kubelet/pods/7c9f9d6b9c-xyz/volumes/kubernetes.io~csi/model-pvc
drwxr-xr-x 2 root 2000 4096 Sep 30 14:15 .
Prevent
- Standardize mount paths: Store the expected checkpoint directory in a Helm value (e.g.,
checkpointPath) and reference it both in the container code and the pod spec. - Enforce securityContext policies: Use a
PodSecurityPolicyorOPA Gatekeeperrule that requiresfsGroupto matchrunAsGroupfor pods mounting PVCs. - Automated permission checks: Add an init container that runs
staton the mount point and exits with a clear error if the UID/GID does not have read/write access. - Monitoring alerts: Create a Prometheus alert on
kube_pod_container_status_waiting_reason{reason="CreateContainerConfigError"}or on container logs containingPermission deniedwithin the first 30 seconds of startup. - Documentation sync: Keep the repository README up‑to‑date with the required
fsGroupandmountPathvalues for each environment (dev, staging, prod).
Related Topic Hub: LLM Systems Troubleshooting Hub
FAQ
- Why does the container work locally but fail in the managed service?
Locally you likely run the image as root or with the host’s user ID, which bypasses thefsGroupmismatch. In the managed service the orchestrator enforces the security context defined in the pod spec. - Can I keep the original mountPath and change the application code instead?
Yes, updatingCHECKPOINT_PATHin the entrypoint or using an environment variable to override the path is a viable alternative, but aligning the mountPath avoids code changes and keeps the container portable. - What if the storage class does not support
fsGroupchanges?
Some CSI drivers (e.g., certain block storage providers) ignorefsGroup. In that case you must either run the container as root or use an init container tochmodthe volume after it is mounted. - Is it safe to set
runAsUser: 0in production?
Running as root removes the isolation benefits of non‑privileged containers and can expose the host to privilege escalation attacks. It should be a last resort and only used behind additional hardening (e.g., seccomp, AppArmor). - How can I debug similar permission issues for other volumes?
Usekubectl execto runidandstatinside the container, and compare against the host’s directory ownership vials -l. Thekubectl describe podoutput will also reveal the effectivefsGroup.