Kubernetes Ingress 404 Path Rewrite: Configure Custom Error Pages and Fallback Routes

Topic: kubernetes-ingress-404-path-rewriteUpdated 8/3/2026

Quick Answer

  • What it does: Rewrites unmatched Kubernetes Ingress requests (404 responses) to a custom path, such as an SPA fallback to index.html or a branded error page.
  • First checks: Confirm your Ingress controller (nginx-ingress, Traefik, HAProxy) supports custom error handling, and verify the annotation or middleware syntax matches your controller version.
  • Minimal fix: For nginx-ingress, add nginx.ingress.kubernetes.io/custom-http-errors: "404" and nginx.ingress.kubernetes.io/error-page-redirect: "/custom-404.html" to your Ingress resource.
  • Environment boundary: Works with Ingress controllers that implement custom error annotations or middleware; the Ingress API itself is stable but controller-specific features vary by version.

What Problem It Solves

Kubernetes Ingress controllers return a default 404 page when a request doesn't match any defined path rule. This default response is often generic, unstyled, and unhelpful for users. The 404 path rewrite pattern solves several practical problems:

ScenarioWithout RewriteWith Rewrite
SPA with client-side routingBrowser shows raw 404All unknown routes serve index.html for the router to handle
API gatewayGeneric "not found" textConsistent JSON error payload
Multi-tenant platformsSame default page for all hostsHost-specific branded 404 pages
Version migrationUsers hit dead endpointsRedirect to new version or helpful guidance

The key advantage is handling this at the Ingress layer rather than modifying application code. Your backend services stay unchanged, and the rewrite logic lives in infrastructure configuration.

When This Error or Setup Appears

You'll need 404 path rewriting when:

  • You deploy a single-page application (React, Vue, Angular) where the frontend router manages routes, but direct URL access (like /dashboard or /settings) returns 404 because no backend service matches that path.
  • You run multiple services behind one Ingress and want unmatched requests to hit a specific fallback service rather than the controller's default error page.
  • You're migrating API versions and want old endpoints to redirect to new ones instead of returning bare 404s.
  • You operate a multi-tenant cluster where each hostname should show its own branded error page.

The setup applies to clusters using nginx-ingress, Traefik, HAProxy Ingress, or similar controllers that support custom error handling.

Minimal Working Configuration

For nginx-ingress, the minimal configuration uses two annotations on your Ingress resource:

YAML
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/custom-http-errors: "404"
    nginx.ingress.kubernetes.io/error-page-redirect: "/custom-404.html"
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-service
                port:
                  number: 80

Apply it with:

BASH
kubectl apply -f ingress.yaml

For Traefik, you need a middleware resource instead:

YAML
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: custom-404
spec:
  errors:
    status:
      - "404"
    query: "/custom-404.html"
    service:
      name: error-service
      port: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    traefik.ingress.kubernetes.io/router.middlewares: default-custom-404@kubernetescrd
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-service
                port:
                  number: 80

Parameters and Environment Variables

The key configuration parameters depend on your Ingress controller:

nginx-ingress annotations:

AnnotationValue FormatPurpose
nginx.ingress.kubernetes.io/custom-http-errorsComma-separated codes (e.g., "404,502")Which HTTP status codes trigger the custom error handling
nginx.ingress.kubernetes.io/error-page-redirectPath starting with / (e.g., "/custom-404.html")Where to redirect the error request
nginx.ingress.kubernetes.io/error-page-locationPath for the error page locationAlternative to error-page-redirect for serving static error content

Traefik middleware parameters:

FieldTypePurpose
statusList of integersHTTP status codes that trigger the error handler
queryStringPath to the error page or service endpoint
serviceObjectBackend service that serves the error response

Important: These annotations are controller-specific. The Ingress API itself has no standard field for custom error handling. Always verify your controller version supports the annotation you're using.

Root Cause Analysis

The 404 path rewrite works by intercepting the controller's error handling flow:

  1. Request arrives at the Ingress controller.
  2. Path matching fails — no rule matches the requested URL.
  3. Controller generates a 404 response using its default error page.
  4. With rewrite configured, the controller instead issues an internal redirect to your specified path.
  5. The redirect request goes through the Ingress rules again, matching your custom error path.
  6. Your error service or static file serves the custom 404 content.

The redirect loop problem occurs when your rewrite target path also matches a rule that triggers the same rewrite. For example, if your error page path /custom-404.html matches a path: / rule with the same rewrite annotations, the controller will loop indefinitely.

Common Errors and Fixes

404 Not Rewritten — Default Page Still Shows

Cause: The annotation is misspelled, unsupported by your controller version, or the Ingress resource isn't associated with the expected controller.

Fix: Verify the annotation spelling against your controller's documentation. Check the controller version with kubectl get pods -n ingress-nginx and confirm it supports custom error annotations. Inspect controller logs:

BASH
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller

Redirect Loop After Rewrite

Cause: The rewrite target path matches an Ingress rule that applies the same rewrite logic.

Fix: Ensure the error page path doesn't match any rule with the rewrite annotations. Use a dedicated path like /errors/404.html and exclude it from other rules, or use pathType: Exact for the error path:

YAML
- path: /errors/404.html
  pathType: Exact
  backend:
    service:
      name: error-service
      port:
        number: 80

Ingress Creation Fails with Invalid Annotation

Cause: The annotation key or value format doesn't match what the controller expects.

Fix: Confirm the annotation is supported by your controller. Check that path values start with /. Review controller logs for the specific validation error:

BASH
kubectl describe ingress my-app-ingress

Rewritten Request Routes to Wrong Service

Cause: Path matching priority conflicts — the rewritten path matches a different rule than intended.

Fix: Use more specific pathType values (Exact instead of Prefix) and order your rules so the error path takes precedence. Review all Ingress rules in the same namespace for overlapping paths.

Production Notes and Security Checks

When deploying 404 path rewriting in production:

Performance considerations:

  • Each rewrite adds an internal redirect, which is negligible for low traffic but can add latency under high load.
  • Large numbers of Ingress rules with error annotations can slow down controller configuration reloads.

Security checks:

  • Never rewrite 404s to sensitive paths like /admin or /internal.
  • Apply access controls to the error page service if it exposes any dynamic content.
  • Audit Ingress rules regularly to prevent path traversal attacks where rewritten paths could reach unintended services.
  • Always terminate TLS at the Ingress and configure proper certificates for the error page host.

Operational notes:

  • Test the rewrite in a staging environment before production rollout.
  • Monitor 404 response codes to ensure the rewrite doesn't accidentally mask real errors.
  • Document which controller version and annotations your team relies on, since these are not part of the standard Ingress API.

FAQ

Q: How do I configure different 404 rewrite paths for different hostnames?

A: The nginx-ingress annotations are global to the Ingress resource, so you can't differentiate by host within a single Ingress. Create separate Ingress resources per hostname, each with its own annotations and error path. For example, one Ingress for api.example.com rewriting to /api-error.json and another for app.example.com rewriting to /index.html.

Q: How does this compare to using Gateway API?

A: The Ingress API is stable and widely supported across controllers, making it the safer choice for simple 404 rewriting. Gateway API is more powerful and extensible but still evolving, with inconsistent controller support. For this specific use case, Ingress annotations are sufficient and more mature. If you anticipate needing advanced traffic management later, evaluate Gateway API as a future migration path.

Q: Will rewriting 404s affect SEO or user experience?

A: It can improve user experience by showing branded, helpful error pages instead of generic ones. However, you must preserve the HTTP 404 status code in the final response. If your rewrite returns a 200 status, search engines won't recognize the page as missing and may index error content incorrectly. Configure your error service to return the original status code, and add appropriate meta tags to the error page.

Related Guides