How to Fix Nginx 404 Not Found on Kubernetes Pod
The Root Cause
On Kubernetes, an Nginx 404 Not Found error most commonly occurs because the Nginx container cannot locate the requested web content within its filesystem, usually due to a mismatch between Nginx’s root directive and the actual path where application files are mounted or copied. This often stems from incorrect volumeMounts in the Pod definition or an improperly configured Dockerfile that places content in an unexpected location.
Quick Fix (CLI)
These commands help diagnose the immediate problem within the running pod:
-
Identify the Nginx Pod:
kubectl get pods -l app=nginx # Adjust label selector as needed -
Access the Pod’s shell:
kubectl exec -it <nginx-pod-name> -- bash -
Inside the Pod, locate
nginx.confand identify itsrootdirective:find / -name nginx.conf # Find the Nginx configuration file cat <path_to_nginx.conf> | grep "root"Common paths for
nginx.conf:/etc/nginx/nginx.conf,/etc/nginx/conf.d/default.conf -
Verify the content exists at the specified
rootpath from the previous step:ls -la <nginx_root_directory> ls -la <nginx_root_directory>/index.html # Or other expected entry file -
Examine Kubernetes Pod definition for volume-related issues (if content is missing or path is incorrect):
exit # Exit the pod shell kubectl describe pod <nginx-pod-name> | grep -E "Volumes:|Volume Mounts:"This helps identify if the correct content source (e.g., ConfigMap, PVC, hostPath) is mounted to the expected
containerPath.
Configuration Check
Based on the diagnosis, the fix will involve editing one or more configuration files:
-
Kubernetes Deployment/Pod Manifest (e.g.,
deployment.yaml):- Verify
volumeMounts: Ensure the path where your application content is expected matches Nginx’srootdirective.containers: - name: nginx image: my-nginx-image:latest volumeMounts: - name: app-content-volume mountPath: /usr/share/nginx/html # This path must match Nginx's root directive volumes: - name: app-content-volume configMap: name: my-app-html-content # Or persistentVolumeClaim, emptyDir, etc. - Check
ConfigMapfornginx.conf(if applicable): If you’re providing a customnginx.confvia a ConfigMap, ensure therootdirective within it is correct.apiVersion: v1 kind: ConfigMap metadata: name: nginx-config data: nginx.conf: | server { listen 80; root /usr/share/nginx/html; # Ensure this path is correct and accessible index index.html index.htm; location / { try_files $uri $uri/ =404; } }
- Verify
-
Dockerfile (if building a custom Nginx image):
- Inspect
COPYcommands: Ensure your application’s static files are copied to the path Nginx expects.FROM nginx:alpine COPY ./build /usr/share/nginx/html # Ensure /usr/share/nginx/html is where Nginx looks # Optionally, copy a custom nginx.conf # COPY ./nginx.conf /etc/nginx/nginx.conf - Rebuild and redeploy the image if Dockerfile changes are made.
- Inspect
Verification
After applying configuration changes and redeploying the affected Pods:
- Port-forward to the Nginx Pod and access locally:
kubectl port-forward <nginx-pod-name> 8080:80 - In a new terminal, test the service:
You should receive the HTML content of your index page (or expected file) instead of a 404.curl http://localhost:8080