Uptime Kuma status pages use the URL pattern /status/{slug}. With a slug of “status”, the full URL becomes /status/status. This post covers redirecting /status to /status/status using NGINX Ingress annotations.

The Problem

Uptime Kuma’s status page URL structure is fixed: /status/{slug}. Creating a status page with slug “status” results in:

https://uptime.minoko.life/status/status

The goal: make /status redirect to /status/status for a cleaner URL.

Configuration Snippets Are Disabled

The obvious solution is an NGINX configuration snippet:

annotations:
  nginx.ingress.kubernetes.io/configuration-snippet: |
    rewrite ^/status$ /status/status permanent;

This fails:

admission webhook "validate.nginx.ingress.kubernetes.io" denied the request:
nginx.ingress.kubernetes.io/configuration-snippet annotation cannot be used.
Snippet directives are disabled by the Ingress administrator

Configuration snippets are disabled by default in NGINX Ingress Controller for security reasons. They allow arbitrary NGINX configuration injection, which can be exploited for request smuggling, header manipulation, and other attacks.

Solution: Separate Ingress with Permanent Redirect

Instead of a configuration snippet, create a second Ingress resource with the permanent-redirect annotation:

# Main ingress for Uptime Kuma
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: uptime-kuma
  namespace: uptime-kuma
spec:
  ingressClassName: nginx
  rules:
    - host: uptime.minoko.life
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: uptime-kuma
                port:
                  number: 80
  tls:
    - hosts:
        - uptime.minoko.life
      secretName: letsencrypt-wildcard
---
# Redirect /status to /status/status
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: uptime-kuma-status-redirect
  namespace: uptime-kuma
  annotations:
    nginx.ingress.kubernetes.io/permanent-redirect: https://uptime.minoko.life/status/status
spec:
  ingressClassName: nginx
  rules:
    - host: uptime.minoko.life
      http:
        paths:
          - path: /status
            pathType: Exact
            backend:
              service:
                name: uptime-kuma
                port:
                  number: 80
  tls:
    - hosts:
        - uptime.minoko.life
      secretName: letsencrypt-wildcard

Key points:

  • pathType: Exact ensures only /status matches, not /status/status or other subpaths
  • permanent-redirect annotation returns a 301 redirect
  • The backend service is still required even though it’s never reached

Apply:

kubectl apply -f ingress.yaml

Verification

curl -sI https://uptime.minoko.life/status | head -5
HTTP/2 301
date: Sun, 18 Jan 2026 12:46:10 GMT
content-type: text/html
content-length: 162
location: https://uptime.minoko.life/status/status

The 301 status and location header confirm the redirect works.

Alternative Annotations

NGINX Ingress provides several redirect-related annotations:

AnnotationBehavior
permanent-redirect301 redirect to specified URL
temporal-redirect302 redirect to specified URL
permanent-redirect-codeCustom 3xx code (default: 301)
from-to-www-redirectRedirect www to non-www or vice versa

The permanent-redirect annotation is the safest option when configuration snippets are disabled, as it only allows redirects to a fixed URL without arbitrary NGINX configuration.

Summary

ApproachWorksSecurity
configuration-snippetNo (disabled)Low - allows arbitrary config
permanent-redirectYesHigh - only redirects allowed
server-snippetNo (disabled)Low - allows arbitrary config

When NGINX Ingress configuration snippets are disabled, use a separate Ingress resource with the permanent-redirect annotation for URL redirects.