Configure NGINX Ingress behavior through two mechanisms: the nginx-configuration ConfigMap for global settings, and per-Ingress annotations for resource-level overrides.
For the complete reference, see the NGINX Ingress ConfigMap documentation or the NGINX Ingress annotations documentation.
ConfigMap
The nginx-configuration ConfigMap controls global defaults for all Ingresses managed by the NGINX Ingress controller.
Edit the ConfigMap
kubectl edit cm -n kube-system nginx-configuration
Default configuration
The following ConfigMap reflects the ACK defaults. Fields not listed here inherit upstream ingress-nginx defaults.
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-configuration
namespace: <namespace> # Default: kube-system
labels:
app: ingress-nginx
data:
log-format-upstream: '$remote_addr - [$remote_addr] - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length $request_time [$proxy_upstream_name] $upstream_addr $upstream_response_length $upstream_response_time $upstream_status $req_id $host [$proxy_alternative_upstream_name]'
proxy-body-size: 20m
proxy-connect-timeout: "10"
max-worker-connections: "65536"
enable-underscores-in-headers: "true"
reuse-port: "true"
worker-cpu-affinity: "auto"
server-tokens: "false"
ssl-redirect: "false"
allow-backend-server-header: "true"
ignore-invalid-headers: "true"
generate-request-id: "true"
upstream-keepalive-timeout: "900"
Field descriptions
| Field | Default | Description |
|---|---|---|
log-format-upstream |
(see above) | Log format for upstream requests. If you change this field, also update the kube-system/k8s-nginx-ingress AliyunLogConfig and the log collection format in Simple Log Service. See Diagnose NGINX Ingress controller access logs in Simple Log Service. |
proxy-body-size |
20m |
Maximum size of the client request body. Maps to client_max_body_size. |
proxy-connect-timeout |
10 |
Timeout (seconds) for establishing a connection with a proxy server. Maximum: 75. For gRPC connections, also set grpc_connect_timeout. See proxy_connect_timeout. |
max-worker-connections |
65536 |
Maximum simultaneous connections per worker process. Set to 0 to use the max-worker-open-files value instead. |
enable-underscores-in-headers |
true |
Whether to allow underscores (_) in request header names. |
reuse-port |
true |
Creates a separate listening socket per worker process using the SO_REUSEPORT socket option, allowing the OS to distribute incoming connections across workers. |
worker-cpu-affinity |
auto |
Automatically binds each worker process to an available CPU core. Useful for high-performance computing workloads. |
server-tokens |
false |
When true, includes the NGINX version in the Server response header and error pages. Set to false to suppress version disclosure. |
ssl-redirect |
false |
When true, globally redirects HTTP to HTTPS (301) for all servers with a TLS certificate. |
allow-backend-server-header |
true |
When true, passes the Server header from the backend service instead of replacing it with a generic NGINX string. |
ignore-invalid-headers |
true |
Whether to ignore invalid header fields in requests. |
generate-request-id |
true |
When true, generates a random X-Request-ID value for requests that do not already include this header. |
upstream-keepalive-timeout |
900 (ACK) / 60 (open source) |
Idle timeout (seconds) for keep-alive connections to upstream servers. Maps to the NGINX keepalive_timeout directive. |
Annotations
Add annotations to individual Ingress resources to override or extend the global ConfigMap settings. Annotations apply only to the Ingress resource they are set on.
For the full list, see the NGINX Ingress annotations documentation.
Load balancing
| Annotation | Type | Description |
|---|---|---|
nginx.ingress.kubernetes.io/load-balance |
round_robin | ewma |
Load balancing algorithm for backend services. round_robin (default) suits most workloads. ewma (Peak Exponential Weighted Moving Average) is better for latency-sensitive applications. |
nginx.ingress.kubernetes.io/upstream-hash-by |
string | Enables consistent hashing. The value is the variable used as the hash key. Examples: $request_uri, $request_uri$host, ${request_uri}-text-value. Consistent hashing uses a circular hash space, so adding or removing nodes only requires migrating a subset of routes. |
Example: consistent hashing by request URI
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-test
namespace: default
annotations:
nginx.ingress.kubernetes.io/upstream-hash-by: "$request_uri"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: <your-service-name>
port:
number: <your-service-port>
For clusters running Kubernetes versions earlier than 1.22, useapiVersion: networking.k8s.io/v1beta1and theserviceName/servicePortfields underbackend.
Cookie affinity
| Annotation | Type | Default | Description |
|---|---|---|---|
nginx.ingress.kubernetes.io/affinity |
cookie |
— | Affinity type. Only cookie is supported. |
nginx.ingress.kubernetes.io/affinity-mode |
balanced | persistent |
balanced |
balanced distributes requests across instances. persistent always routes a client to the same backend instance, ensuring session consistency. |
nginx.ingress.kubernetes.io/session-cookie-name |
string | — | Cookie name used as the hash key for session routing. |
nginx.ingress.kubernetes.io/session-cookie-path |
string | / |
Path attribute set on the session cookie. Does not support regular expressions when nginx.ingress.kubernetes.io/use-regex is true. |
nginx.ingress.kubernetes.io/session-cookie-max-age |
integer (seconds) | — | Max-Age attribute of the session cookie (seconds). |
nginx.ingress.kubernetes.io/session-cookie-expires |
integer (seconds) | — | Time from cookie creation to expiration (seconds). Sets the Expires attribute. |
Example: cookie-based session affinity
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-test
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie"
nginx.ingress.kubernetes.io/session-cookie-name: "route"
nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
spec:
ingressClassName: nginx
rules:
- host: stickyingress.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: http-svc
port:
number: 80
Redirects
| Annotation | Type | Default | Description |
|---|---|---|---|
nginx.ingress.kubernetes.io/ssl-redirect |
"true" | "false" |
— | Redirects HTTP to HTTPS for this Ingress when it has a TLS certificate. See HTTP-to-HTTPS redirect. |
nginx.ingress.kubernetes.io/force-ssl-redirect |
"true" | "false" |
"false" |
Forces HTTP-to-HTTPS redirect regardless of whether a TLS certificate is configured. |
nginx.ingress.kubernetes.io/permanent-redirect |
URL | — | Destination URL for a permanent redirect. Must include a scheme (http:// or https://). |
nginx.ingress.kubernetes.io/permanent-redirect-code |
integer | 301 |
HTTP status code for the permanent redirect. |
nginx.ingress.kubernetes.io/temporal-redirect |
URL | — | Destination URL for a temporary redirect. Must include a scheme (http:// or https://). |
nginx.ingress.kubernetes.io/app-root |
path | — | Redirects requests to / to the specified application root path. |
Example: permanent redirect from `foo.com` to `bar.com`
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/permanent-redirect: "https://bar.com"
spec:
ingressClassName: nginx
rules:
- host: foo.com
http:
paths:
- path: "/"
pathType: ImplementationSpecific
backend:
service:
name: httpbin
port:
number: 8000
Rewrites
| Annotation | Type | Description |
|---|---|---|
nginx.ingress.kubernetes.io/rewrite-target |
string | Destination path for the rewrite. Supports capture groups. See Configure URL redirection. |
nginx.ingress.kubernetes.io/upstream-vhost |
string | Rewrites the Host header sent to the upstream service. |
Example: rewrite the `Host` header to `test.com` for requests to `example.com/test`
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: demo
annotations:
nginx.ingress.kubernetes.io/upstream-vhost: "test.com"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /test
pathType: ImplementationSpecific
backend:
service:
name: demo-service
port:
number: 80
Throttling
Use throttling annotations to limit request rates and concurrent connections per client IP address, protecting backend services from traffic spikes.
| Annotation | Type | Default | Description |
|---|---|---|---|
nginx.ingress.kubernetes.io/limit-connections |
integer | — | Maximum concurrent connections per IP address. Requests exceeding this limit receive a 503 response. |
nginx.ingress.kubernetes.io/limit-rate |
integer (KB) | — | Maximum data transmitted per connection per second (KB). Set to 0 to disable. Requires proxy buffering to be enabled. |
nginx.ingress.kubernetes.io/limit-rps |
integer | — | Maximum requests per second per IP address. Requests exceeding the burst limit (rate × limit-burst-multiplier) return a limit-req-status-code error (503 by default). |
nginx.ingress.kubernetes.io/limit-rpm |
integer | — | Maximum requests per minute per IP address. Same burst behavior as limit-rps. |
nginx.ingress.kubernetes.io/limit-burst-multiplier |
integer | 5 |
Multiplier for calculating the burst rate limit. |
nginx.ingress.kubernetes.io/limit-whitelist |
CIDR list | — | Comma-separated CIDR blocks excluded from throttling. |
Example: rate limiting with an IP whitelist
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/limit-rate: "100K"
nginx.ingress.kubernetes.io/limit-rps: "1"
nginx.ingress.kubernetes.io/limit-rpm: "30"
nginx.ingress.kubernetes.io/limit-whitelist: "10.1.10.100"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 80
Fallback
Use fallback annotations to route traffic to a backup service when the primary backend is unavailable.
| Annotation | Type | Description |
|---|---|---|
nginx.ingress.kubernetes.io/default-backend |
string | Fallback service to receive requests when no backend nodes are available. Configure globally via the Add-ons page in the ACK console. |
nginx.ingress.kubernetes.io/custom-http-errors |
HTTP status codes | Works with default-backend. When the backend returns one of the specified status codes, NGINX forwards the request to the fallback service. The request path is rewritten to / when forwarded (consistent with upstream ingress-nginx behavior). Overrides the global custom-http-errors ConfigMap setting for paths in this Ingress. |
Canary releases
Use canary annotations to implement canary releases and blue-green deployments. For a full walkthrough, see Use the NGINX Ingress controller to implement canary releases and blue-green deployments.
| Annotation | Type | Description |
|---|---|---|
nginx.ingress.kubernetes.io/canary |
"true" | "false" |
Specifies whether to enable the canary release feature. |
nginx.ingress.kubernetes.io/canary-by-header |
string | Request header key used for traffic splitting. |
nginx.ingress.kubernetes.io/canary-by-header-value |
string | Exact-match value for the header key. Routes matching requests to the canary. |
nginx.ingress.kubernetes.io/canary-by-header-pattern |
regex | Regular expression match for the header value. |
nginx.ingress.kubernetes.io/canary-by-cookie |
string | Cookie key used for traffic splitting. |
nginx.ingress.kubernetes.io/canary-weight |
integer | Percentage of traffic routed to the canary (0–canary-weight-total). |
nginx.ingress.kubernetes.io/canary-weight-total |
integer | Total weight used as the denominator for canary-weight. |
Timeout
Global timeout settings
Edit the nginx-configuration ConfigMap to set timeouts globally:
kubectl edit cm -n kube-system nginx-configuration
| Field | Default | Description |
|---|---|---|
proxy-connect-timeout |
5s |
Timeout for establishing a connection with the proxy server. Maximum: 75s. |
proxy-read-timeout |
60s |
Timeout between two consecutive reads from the proxy server (not the total response time). |
proxy-send-timeout |
60s |
Timeout between two consecutive writes to the proxy server (not the total request transmission time). |
proxy-stream-next-upstream-timeout |
600s |
Maximum time allowed to pass a connection to the next upstream server. Set to 0 for no limit. |
proxy-stream-timeout |
600s |
Timeout between consecutive reads or writes on client or proxy connections. The connection closes if no data is transferred within this period. |
upstream-keepalive-timeout |
900s (ACK) / 60s (open source) |
Idle timeout for keep-alive connections to upstream servers. |
worker-shutdown-timeout |
240s |
Graceful shutdown timeout. |
proxy-protocol-header-timeout |
5s |
Timeout for receiving the PROXY protocol header, preventing TLS passthrough handlers from waiting indefinitely on broken connections. |
ssl-session-timeout |
10m |
Validity period for SSL session parameters in the session cache. Each session cache entry uses approximately 0.25 MB. |
client-body-timeout |
60s |
Timeout for reading the client request body. |
client-header-timeout |
60s |
Timeout for reading the client request headers. |
Per-Ingress timeout settings
Override global timeouts for specific Ingresses using these annotations:
| Annotation | Description |
|---|---|
nginx.ingress.kubernetes.io/proxy-connect-timeout |
Timeout for establishing a connection with the proxy server. |
nginx.ingress.kubernetes.io/proxy-send-timeout |
Timeout for sending data to the proxy server. |
nginx.ingress.kubernetes.io/proxy-read-timeout |
Timeout for reading data from the proxy server. |
nginx.ingress.kubernetes.io/proxy-request-buffering |
Request buffering mode. on: buffer the full request before forwarding (HTTP/1.1 chunked requests are always buffered). off: stream request data directly; no retry on transmission errors. |
CORS
Configure cross-origin resource sharing (CORS) to allow browser clients to access resources from different origins. For more details, see Configure CORS on NGINX Ingresses.
| Annotation | Description |
|---|---|
nginx.ingress.kubernetes.io/enable-cors |
Enables CORS for this Ingress. |
nginx.ingress.kubernetes.io/cors-allow-origin |
Specifies the allowed third-party sites for CORS. |
nginx.ingress.kubernetes.io/cors-allow-methods |
Specifies the allowed request methods for CORS. The allowed request methods include GET, POST, and PUT. |
nginx.ingress.kubernetes.io/cors-allow-headers |
Allowed request headers. |
nginx.ingress.kubernetes.io/cors-expose-headers |
Response headers exposed to the browser. |
nginx.ingress.kubernetes.io/cors-allow-credentials |
Whether to allow credentials (cookies, authorization headers) in CORS requests. |
nginx.ingress.kubernetes.io/cors-max-age |
How long (seconds) the browser can cache CORS preflight results. |
Retry policies
| Annotation | Default | Description |
|---|---|---|
nginx.ingress.kubernetes.io/proxy-next-upstream-tries |
3 |
Number of retries when a retry condition is met. |
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout |
— | Timeout (seconds) for the entire retry sequence. No default (unlimited). |
nginx.ingress.kubernetes.io/proxy-next-upstream |
— | Retry conditions. Separate multiple values with spaces. Valid values: error (connection failure), timeout (timeout), invalid_response (invalid status code), http_500, http_502, http_503, http_504, http_403, http_404, http_429, off (disable retries). |
IP address-based access control
| Annotation | Type | Description |
|---|---|---|
nginx.ingress.kubernetes.io/whitelist-source-range |
CIDR list | IP allowlist. Only requests from the listed IP addresses or CIDR blocks are allowed. Separate multiple entries with commas. |
nginx.ingress.kubernetes.io/denylist-source-range |
CIDR list | IP blocklist. Requests from the listed IP addresses or CIDR blocks are denied. Separate multiple entries with commas. |
Example: allow only a specific IP address
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/whitelist-source-range: "10.1.10.2"
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-svc
port:
number: 80
To apply an IP allowlist globally, edit the nginx-configuration ConfigMap and set whitelist-source-range.
Traffic mirroring
Traffic mirroring duplicates production requests to a shadow environment, letting you test new versions or configurations without affecting live traffic. For a full walkthrough, see Use an Ingress controller to mirror network traffic.
| Annotation | Type | Description |
|---|---|---|
nginx.ingress.kubernetes.io/mirror-target |
URL | Mirror destination. Accepts a Service IP address or external URL. Use $request_uri to append the original request URI. Example: https://test.env.com/$request_uri. |
nginx.ingress.kubernetes.io/mirror-request-body |
"true" | "false" |
Whether to mirror the request body. |
nginx.ingress.kubernetes.io/mirror-host |
string | Host header sent with mirrored requests. |
Security protection
Configure TLS to encrypt communications between clients and the NGINX Ingress controller, and between the controller and backend services. For more details, see NGINX Ingress controller encryption.
Client-to-gateway encryption
| Annotation | Scope | Description |
|---|---|---|
nginx.ingress.kubernetes.io/ssl-cipher |
Domain | TLS cipher suites (comma-separated). Takes effect only for TLS 1.0–1.2 handshakes. Default cipher suites: ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-RSA-AES128-SHA, AES128-GCM-SHA256, AES128-SHA, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-RSA-AES256-SHA, AES256-GCM-SHA384, AES256-SHA. |
nginx.ingress.kubernetes.io/auth-tls-secret |
Domain | Secret containing the certificate authority (CA) certificate used to verify client certificates during mutual TLS (mTLS) handshakes. The Secret must include a ca.crt file with the complete CA chain. |
Gateway-to-backend encryption
| Annotation | Scope | Description |
|---|---|---|
nginx.ingress.kubernetes.io/proxy-ssl-secret |
Service | Secret containing the client certificate the gateway presents to backend services. Must be in Privacy Enhanced Mail (PEM) format and include tls.crt (client certificate), tls.key (private key), and ca.crt (trusted CA certificate). Specify as "namespace/secretName". |
nginx.ingress.kubernetes.io/proxy-ssl-name |
Service | Server Name Indication (SNI) value sent during the TLS handshake with the backend. |
nginx.ingress.kubernetes.io/proxy-ssl-server-name |
Service | Enables or disables SNI for the TLS handshake with the backend. |
Security authentication
Use Basic Authentication to restrict access to your applications. Only requests with valid credentials are forwarded to backend services.
| Annotation | Scope | Description |
|---|---|---|
nginx.ingress.kubernetes.io/auth-type |
Ingress | Authentication type. Set to basic. |
nginx.ingress.kubernetes.io/auth-secret |
Ingress | Name of the Secret containing credentials, in the namespace/secretName format. |
nginx.ingress.kubernetes.io/auth-secret-type |
Ingress | Format of the Secret data. auth-file: the auth key contains newline-separated username:password entries. auth-map: each key is a username and the corresponding value is the password. |
nginx.ingress.kubernetes.io/auth-realm |
Ingress | Authentication realm shown to the client when prompting for credentials. |
Set up Basic Authentication
-
Generate a password file using
htpasswd:htpasswd -c auth jokerVerify the file:
cat auth # Expected output: joker:$apr1$R.G4krs/$hh0mX8xe4A3lYKMjvlVs1/ -
Create a Secret from the password file:
kubectl create secret generic basic-auth --from-file=auth -
Add the annotations to your Ingress:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-nginx annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: basic-auth spec: ingressClassName: nginx rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: backend-svc port: number: 80