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: Exactensures only/statusmatches, not/status/statusor other subpathspermanent-redirectannotation 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:
| Annotation | Behavior |
|---|---|
permanent-redirect | 301 redirect to specified URL |
temporal-redirect | 302 redirect to specified URL |
permanent-redirect-code | Custom 3xx code (default: 301) |
from-to-www-redirect | Redirect 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
| Approach | Works | Security |
|---|---|---|
configuration-snippet | No (disabled) | Low - allows arbitrary config |
permanent-redirect | Yes | High - only redirects allowed |
server-snippet | No (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.