This error occurs when the Ingress controller cannot route traffic to a backend service. Fix it by verifying the service exists, checking label selectors match pods, ensuring correct path configuration, and adding rewrite annotations if needed.
The "default backend - 404" error indicates that the Ingress controller received a request but couldn't find a matching rule to route it to a backend service. When no rules match, traffic goes to the default backend, which returns a 404 Not Found response. This typically happens when the hostname in the request doesn't match any Ingress rule, the path doesn't match, or the backend service doesn't exist or has no endpoints. The Ingress controller can only route traffic to services that exist and have healthy pods. The error can also occur when path-based routing is misconfigured—the Ingress forwards the original path to the backend, but the backend application expects a different path (usually root /).
Check Ingress class is configured correctly:
# List available ingress classes
kubectl get ingressclasses
# Describe ingress to see current configuration
kubectl describe ingress my-ingress -n defaultEnsure Ingress has correct class:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: "nginx" # For older versions
spec:
ingressClassName: nginx # For Kubernetes 1.18+Check if the backend service exists and has healthy endpoints:
# List services
kubectl get svc -n default
# Check endpoints (should show pod IPs)
kubectl get endpoints my-service -n default
# If endpoints are empty, check pod labels
kubectl get pods --show-labels
kubectl get svc my-service -o jsonpath='{.spec.selector}'If endpoints show <none>, the service selector doesn't match any pod labels.
When using path-based routing, add rewrite annotation:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080Without rewrite-target, backend receives /api/users when client requests /api/users. With rewrite-target: /, backend receives /users.
For capture groups:
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- path: /api(/|$)(.*)
pathType: ImplementationSpecificTest that hostname resolves and matches Ingress rule:
# Get ingress IP
kubectl get ingress my-ingress
# Test with explicit host header
curl -H "Host: example.com" http://<ingress-ip>/
# Or test via hostname
curl http://example.com/Ensure Ingress hosts match your request:
spec:
rules:
- host: example.com # Must match Host header exactly
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-service
port:
number: 80Check ingress controller logs for routing errors:
# Find ingress controller pod
kubectl get pods -n ingress-nginx
# Stream logs
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx -f
# Search for specific ingress
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller | grep "my-ingress"Look for:
- "add rules for service" messages
- "successfully generated endpoint group"
- Any error messages about missing services
Verify the service works independently of Ingress:
# Port-forward to test service directly
kubectl port-forward svc/my-service 8080:80 -n default
# Then: curl http://localhost:8080/
# Or exec into a pod and test
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- \
curl http://my-service.default.svc.cluster.local:80/If service works directly but not through Ingress, the issue is in Ingress configuration.
Path Type Behavior:
- Prefix: Matches URL path prefix split by /. Path /app matches /app, /app/users
- Exact: Exact case-sensitive match. Path /app matches only /app
- ImplementationSpecific: Vendor-specific (NGINX uses regex)
Rewrite-Target Patterns:
- Simple strip: rewrite-target: / strips the matched path
- Capture groups: path: /api(/|$)(.*) with rewrite-target: /$2 keeps path after /api
Common Path Mistakes:
- Missing rewrite annotation causes backend to receive /api when it expects /
- pathType not specified leads to ambiguous behavior
- Trailing slashes can cause mismatches
Traefik-Specific: Traefik uses middleware for path stripping:
annotations:
traefik.ingress.kubernetes.io/router.middlewares: namespace-strip@kubernetescrdNo subnets found for EKS cluster
How to fix "eks subnet not found" in Kubernetes
unable to compute replica count
How to fix "unable to compute replica count" in Kubernetes HPA
error: context not found
How to fix "error: context not found" in Kubernetes
serviceaccount cannot list resource
How to fix "serviceaccount cannot list resource" in Kubernetes
must specify requests.cpu, requests.memory
How to fix "must specify requests.cpu, requests.memory" in Kubernetes