NGINX Ingress Migration Tool
kubernetes/ingress-nginx project reaches end of maintenance at the end of March 2026. It will receive no further releases, bugfixes, or security patches. The F5 NGINX Ingress Controller (nginx/kubernetes-ingress) is actively maintained and is the recommended migration target.Overview
This interactive guide helps you migrate from the community-maintained Kubernetes Ingress NGINX (Ingress-NGINX) controller (kubernetes/ingress-nginx) to the F5 NGINX Ingress Controller (nginx/kubernetes-ingress). It covers 130+ annotation mappings, ConfigMap key translations, and CRD migration examples across three tabs:
- Getting Started — Background on why to migrate, CRD overviews, installation, and a migration checklist
- Ingress NGINX Config Analyzer — Paste an Ingress manifest and get automatic migration suggestions with ready-to-use YAML
- Reference Guide — Complete annotation and ConfigMap mapping tables with side-by-side examples
Why Migrate?
The two controllers take fundamentally different approaches to configuring NGINX in Kubernetes.
- Kubernetes Ingress NGINX (Ingress-NGINX) is annotation-driven — it relies on annotations and ConfigMap keys to customize NGINX. These are opaque strings with no schema validation — a single Ingress resource may carry dozens of annotations as unstructured key-value pairs.
- F5 NGINX Ingress Controller is CRD-native — it uses Custom Resource Definitions (VirtualServer, Policy, TransportServer) as its primary config model, providing structured, schema-validated YAML with IDE autocompletion.
While the F5 NGINX Ingress Controller still supports annotations for common settings, CRDs unlock capabilities that annotations cannot express:
- Schema validation — Kubernetes validates CRD fields at apply time, catching misconfigurations before they reach NGINX
- Structured configuration — Nested YAML objects replace long annotation strings, making complex routing, traffic splitting, and security policies readable and maintainable
- Reusability — Policies (rate limiting, auth, WAF) are defined once and attached to any number of routes
- Layer 4 support — TransportServer CRDs handle TCP/UDP workloads that annotations cannot express
- IDE and tooling support — CRD schemas enable autocompletion, linting, and documentation in editors and CI pipelines
CRDs Summary
The F5 NGINX Ingress Controller uses Custom Resource Definitions (CRDs) to extend Kubernetes with NGINX-specific configuration. CRDs provide type-safe, validated configuration that goes beyond what standard Ingress annotations can offer.
VirtualServer CRD
The primary CRD for configuring HTTP/HTTPS load balancing. It replaces Ingress resources and provides advanced traffic management capabilities with full validation.
- Traffic Splitting: Route percentages of traffic to different backends for canary/blue-green deployments
- Content-Based Routing: Route based on headers, cookies, arguments, or variables
- Path Rewriting: Modify request URIs with regex support before forwarding to backends
- Error Pages: Custom responses for specific HTTP error codes
- Request/Response Headers: Add, modify, or remove headers in transit
- Health Checks: Active health monitoring of upstream servers
- Session Persistence: Cookie-based sticky sessions (Plus)
VirtualServerRoute CRD
Enables delegation of route configuration to different namespaces. Allows teams to manage their own routing rules while maintaining centralized control over the domain.
- Cross-Namespace Routing: Reference services in different namespaces
- Path Delegation: Delegate path prefixes to other teams/namespaces
- Independent Updates: Teams update routes without modifying the parent VirtualServer
- Access Control: Limit which namespaces can define routes for a host
Policy CRD
Reusable security and traffic policies that can be attached to VirtualServers or specific routes. Policies enable consistent security controls across multiple applications.
- Rate Limiting: Limit request rates by IP, header, or custom key
- Access Control: IP allowlists and denylists
- Basic Auth: Username/password authentication via htpasswd
- JWT Validation: Validate JSON Web Tokens (Plus)
- OIDC: Native OpenID Connect integration (Plus)
- API Key Auth: Authenticate via API keys in headers/query (Plus)
- mTLS: Client certificate verification (ingress) and backend TLS (egress)
- WAF: F5 WAF for NGINX web application firewall (Plus)
TransportServer CRD
Configures TCP/UDP load balancing for non-HTTP protocols. Essential for databases, message queues, gaming servers, and other Layer 4 applications.
- TCP Load Balancing: MySQL, PostgreSQL, Redis, custom TCP services
- UDP Load Balancing: DNS, RADIUS, gaming protocols
- TLS Passthrough: Pass encrypted traffic directly to backends
- Health Checks: TCP/UDP health monitoring
- Session Persistence: IP hash-based session affinity
GlobalConfiguration CRD
Cluster-wide configuration for the F5 NGINX Ingress Controller. Defines global listeners for TCP/UDP and TLS passthrough that TransportServers can reference.
- TCP/UDP Listeners: Define ports for non-HTTP traffic
- TLS Passthrough Listeners: Configure SNI-based routing
- Global Settings: Controller-wide configuration options
Installing CRDs
CRDs can be installed via Helm or manually using manifests, depending on your deployment method. See the F5 NGINX Ingress Controller installation docs for full instructions.
Helm (example)
If you install the F5 NGINX Ingress Controller via Helm, CRDs are included automatically. To ensure they are enabled:
helm install nginx-ingress oci://ghcr.io/nginx/charts/nginx-ingress --version 2.1.0 --set controller.enableCRDs=true
The controller.enableCRDs flag is true by default. If you previously disabled it, re-enable it to use CRD resources. See the Helm installation guide for details.
Manifests (example)
If you deploy using manifests, install CRDs manually before deploying the controller:
kubectl apply -f https://raw.githubusercontent.com/nginx/kubernetes-ingress/v5.3.4/deploy/crds.yaml
Replace the version number with your target controller version. See the manifest installation guide for the full step-by-step process.
crds.yaml file contains all CRDs (VirtualServer, VirtualServerRoute, Policy, TransportServer, GlobalConfiguration) in a single manifest.Migration Checklist
- Install CRDs via Helm (
controller.enableCRDs=true) or manifests (deploy/crds.yaml) - Review annotation mappings — not all
nginx.ingress.kubernetes.io/annotations have a directnginx.org/equivalent (see NGINX Mappings) - Map rewrite-target annotation to
nginx.org/rewrite-target(notnginx.org/rewrites) - Migrate ConfigMap keys that differ between controllers (see ConfigMap Mappings)
- Convert HSTS ConfigMap keys to
nginx.org/hstsannotations for per-Ingress control - Convert
server-tokensConfigMap key tonginx.org/server-tokensannotation - Convert access control annotations to Policy CRD (
accessControl) - Convert authentication annotations to Policy CRD (
basicAuth,jwt,oidc,apiKey) - Convert canary/traffic splitting to VirtualServer
splits/matches - Convert mTLS annotations to
ingressMTLS/egressMTLSpolicies - Convert CORS annotations to
location-snippetsorserver-snippets - Convert custom error pages to VirtualServer
errorPages - Convert header manipulation to VirtualServer
requestHeaders/responseHeaders - Convert rate limiting annotations to Policy CRD (
rateLimit) - Convert redirect annotations to VirtualServer
action.redirect - Convert session affinity annotations to VirtualServer upstream
sessionCookie - Convert SSL passthrough to TransportServer CRD
- Convert TCP/UDP services to TransportServer CRD
- Replace
ssl-redirectwithnginx.org/ssl-redirect(not the deprecatedingress.kubernetes.io/ssl-redirect) - Verify snippets (
configuration-snippet,server-snippet) use F5 NGINX Ingress Controller equivalents - Test in staging environment
- Update monitoring and alerting
Phased Migration Strategy
Rather than performing a "big bang" cutover, F5 recommends a phased migration that allows you to validate each workload before decommissioning the community controller. Both controllers can run side-by-side in the same cluster using separate IngressClass resources.
- Deploy side-by-side — Install the F5 NGINX Ingress Controller alongside the community controller using a distinct
IngressClass(e.g.,nginx-nic). This ensures existing traffic is unaffected. - Migrate service-by-service — Update each Ingress resource's
ingressClassNameto point to the new controller. Convert annotations as described in the Reference Guide, validate routing and TLS behavior, and promote to production before moving on to the next service. - Decommission — After all workloads have been migrated and validated, remove the community controller deployment, its
IngressClass, and any unused ConfigMaps.
Additional Resources
kubernetes/ingress-nginx project reaches end of maintenance at the end of March 2026. It will receive no further releases, bugfixes, or security patches. The F5 NGINX Ingress Controller (nginx/kubernetes-ingress) is actively maintained and is the recommended migration target.Ingress NGINX Config Analyzer
Paste a Kubernetes Ingress YAML manifest that uses Kubernetes Ingress NGINX (Ingress-NGINX) annotations to get migration suggestions for the F5 NGINX Ingress Controller.
kubernetes/ingress-nginx project reaches end of maintenance at the end of March 2026. It will receive no further releases, bugfixes, or security patches. The F5 NGINX Ingress Controller (nginx/kubernetes-ingress) is actively maintained and is the recommended migration target.Key Differences
| Aspect | Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|---|
| Repository | kubernetes/ingress-nginx | nginx/kubernetes-ingress |
| Annotation Prefix | nginx.ingress.kubernetes.io/ | nginx.org/ or nginx.com/ or appprotect.f5.com/ |
| CRD Support | Limited | VirtualServer, VirtualServerRoute, Policy, TransportServer, GlobalConfiguration |
| NGINX Plus Support | No | Yes (with nginx.com/ annotations) |
NGINX Mappings
These features are available in both NGINX Open Source and NGINX Plus editions. All items are annotations unless otherwise indicated with a badge (e.g. ConfigMap, Policy CRD, VirtualServer CRD). Community annotations use the nginx.ingress.kubernetes.io/ prefix; F5 NGINX Ingress Controller annotations use nginx.org/.
- Annotation-to-annotation rows ▶: Direct mappings where you change the annotation name/prefix. Click to expand and see before/after Ingress YAML examples.
- CRD-based rows ▶: Annotations that map to a CRD (VirtualServer, Policy, or TransportServer). Click to expand for full CRD examples with installation instructions.
- Grouped annotations: Related annotations that work together are grouped in a single expandable row, showing how they map to a unified configuration.
- F5 NGINX Ingress Controller-only rows: Rows marked No direct equivalent on the left are features unique to the F5 NGINX Ingress Controller with no community equivalent.
Access Control
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/denylist-source-rangenginx.ingress.kubernetes.io/whitelist-source-range |
Policy CRD accessControl |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/satisfy |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Authentication (Basic)
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/auth-realmnginx.ingress.kubernetes.io/auth-secretnginx.ingress.kubernetes.io/auth-secret-typenginx.ingress.kubernetes.io/auth-type: "basic" |
Policy CRD basicAuth— or —nginx.org/basic-auth-secretnginx.org/basic-auth-realm |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller
Note: The community
auth-secret-type annotation
(auth-file or auth-map) has no F5 NGINX Ingress Controller equivalent.
The F5 NGINX Ingress Controller only supports htpasswd format, specified via the
Secret's type: nginx.org/htpasswd field. The auth-type
annotation is also implicit — the F5 NGINX Ingress Controller only supports basic auth
via these annotations.
| |
Buffering
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/client-body-buffer-size |
VirtualServer CRD upstreams[].client-body-buffer-size— or —nginx.org/client-body-buffer-size |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-body-size |
VirtualServer CRD upstreams[].client-max-body-size— or —nginx.org/client-max-body-size |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-buffer-size |
VirtualServer CRD upstreams[].buffer-size— or —nginx.org/proxy-buffer-size |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-buffering |
VirtualServer CRD upstreams[].buffering— or —nginx.org/proxy-buffering |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-buffers-number |
VirtualServer CRD upstreams[].buffers— or —nginx.org/proxy-buffers |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller annotation uses a combined format:
"number size" (e.g., "4 8k").Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-busy-buffers-size |
VirtualServer CRD upstreams[].busy-buffers-size— or —nginx.org/proxy-busy-buffers-size |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-max-temp-file-size |
nginx.org/proxy-max-temp-file-size |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-request-buffering |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller does not have a dedicated
proxy-request-buffering annotation or ConfigMap key. Use location-snippets to set the proxy_request_buffering directive. | |
Canary / Traffic Splitting
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/canarynginx.ingress.kubernetes.io/canary-by-cookienginx.ingress.kubernetes.io/canary-by-headernginx.ingress.kubernetes.io/canary-by-header-patternnginx.ingress.kubernetes.io/canary-by-header-valuenginx.ingress.kubernetes.io/canary-weightnginx.ingress.kubernetes.io/canary-weight-total |
VirtualServer CRD splits[], matches[] |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Configuration Snippets
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/configuration-snippet |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/server-snippet |
VirtualServer CRD server-snippets— or —nginx.org/server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/stream-snippet |
GlobalConfiguration CRD +TransportServer CRD |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
CORS / Header Manipulation
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/cors-allow-credentialsnginx.ingress.kubernetes.io/cors-allow-headersnginx.ingress.kubernetes.io/cors-allow-methodsnginx.ingress.kubernetes.io/cors-allow-originnginx.ingress.kubernetes.io/cors-expose-headersnginx.ingress.kubernetes.io/cors-max-agenginx.ingress.kubernetes.io/enable-cors |
VirtualServer CRD responseHeaders— or —nginx.org/location-snippetsnginx.org/server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerRecommended: The
responseHeaders approach provides a fully declarative way to manage CORS and other response headers without raw NGINX snippets. Headers are set per-route via action.proxy.responseHeaders, and the always flag ensures headers are added regardless of response status code. See the VirtualServer CRD docs for additional options like hide, ignore, and pass.Note: The F5 NGINX Ingress Controller does not have dedicated CORS annotations. Two approaches are available: (1)
server-snippets / location-snippets via Ingress annotations for a quick migration, or (2) responseHeaders on VirtualServer routes for a fully declarative, snippet-free approach. The responseHeaders approach is recommended for new deployments as referenced in the official migration guide. | |
Error Handling
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/custom-http-errorsnginx.ingress.kubernetes.io/default-backend |
VirtualServer CRD errorPages[] |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Headers
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/connection-proxy-header |
VirtualServer CRD requestHeaders.set— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/custom-headers |
VirtualServer CRD responseHeaders.add |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/upstream-vhostnginx.ingress.kubernetes.io/x-forwarded-prefix |
VirtualServer CRD requestHeaders.set |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
HSTS
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
ConfigMap hstsConfigMap hsts-max-ageConfigMap hsts-include-subdomainsConfigMap hsts-preload |
nginx.org/hstsnginx.org/hsts-max-agenginx.org/hsts-include-subdomainsnginx.org/hsts-behind-proxy |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: HSTS annotations are F5 NGINX Ingress Controller-only and provide per-Ingress control. The community controller handles HSTS via ConfigMap only. Note that
hsts-preload from the community ConfigMap does not have a direct annotation equivalent in the F5 NGINX Ingress Controller. | |
Load Balancing
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/load-balance |
VirtualServer CRD upstreams[].lb-method— or —nginx.org/lb-method |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: Supported methods differ. The F5 NGINX Ingress Controller supports:
round_robin, least_conn, ip_hash, hash, random. The F5 NGINX Ingress Controller's default is random two least_conn (not round_robin), so load balancing behavior may change even without explicit configuration. | |
nginx.ingress.kubernetes.io/service-upstream |
VirtualServer CRD upstreams[].use-cluster-ip— or —nginx.org/use-cluster-ip |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/upstream-hash-bynginx.ingress.kubernetes.io/upstream-hash-by-subsetnginx.ingress.kubernetes.io/upstream-hash-by-subset-size |
VirtualServer CRD upstreams[].lb-method— or —nginx.org/lb-method |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller has no dedicated
upstream-hash-by equivalent. Instead, the hash key is specified as part of the lb-method value (e.g., hash $request_uri consistent). Subset hashing (upstream-hash-by-subset) is not supported; use consistent hashing for similar distribution. | |
mTLS (Client Certificate Verification)
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/auth-tls-error-pagenginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstreamnginx.ingress.kubernetes.io/auth-tls-secretnginx.ingress.kubernetes.io/auth-tls-verify-clientnginx.ingress.kubernetes.io/auth-tls-verify-depth |
Policy CRD ingressMTLS + nginx.org/location-snippets / server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/auth-tls-match-cn |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller's
ingressMTLS Policy does not have a built-in CN matching feature. Use location-snippets to add custom CN validation logic. | |
mTLS (Backend/Egress)
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/proxy-ssl-ciphersnginx.ingress.kubernetes.io/proxy-ssl-namenginx.ingress.kubernetes.io/proxy-ssl-protocolsnginx.ingress.kubernetes.io/proxy-ssl-secretnginx.ingress.kubernetes.io/proxy-ssl-server-namenginx.ingress.kubernetes.io/proxy-ssl-verifynginx.ingress.kubernetes.io/proxy-ssl-verify-depth |
Policy CRD egressMTLS |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Miscellaneous
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/enable-access-log |
ConfigMap access-log-off |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/enable-rewrite-log |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller does not have a dedicated
rewrite-log ConfigMap key. Use location-snippets to enable the rewrite_log directive. Rewrite logging outputs to the error log at notice level. | |
nginx.ingress.kubernetes.io/enable-opentelemetry |
ConfigMap otel-exporter-endpointConfigMap otel-trace-in-httpConfigMap otel-service-name |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller uses
otel-exporter-endpoint, otel-trace-in-http, otel-service-name, otel-exporter-header-name, and otel-exporter-header-value ConfigMap keys for OpenTelemetry. Set otel-trace-in-http: "false" to disable global tracing and control it per-route via snippets instead. | |
nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span |
ConfigMap otel-exporter-endpointConfigMap otel-trace-in-httpConfigMap otel-service-name |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community
opentelemetry-trust-incoming-span annotation enables per-Ingress control over whether to trust incoming trace context. The F5 NGINX Ingress Controller configures OpenTelemetry globally via ConfigMap keys (otel-trace-in-http, otel-exporter-endpoint). Per-Ingress OTel toggling is not supported; tracing applies to all routes when enabled globally. | |
http2-push-preload |
Not supported |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: HTTP/2 Server Push (
http2_push_preload) was removed from NGINX in version 1.25.1 after major browsers deprecated the feature. This annotation can be safely removed during migration. | |
nginx.ingress.kubernetes.io/mirror-targetnginx.ingress.kubernetes.io/mirror-request-bodynginx.ingress.kubernetes.io/mirror-host |
VirtualServer CRD location-snippets / server-snippets— or —nginx.org/location-snippetsnginx.org/server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-http-version |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller does not have a dedicated annotation for HTTP version. Use
location-snippets to set proxy_http_version directly. | |
nginx.ingress.kubernetes.io/server-alias |
VirtualServer CRD one resource per hostname |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community
server-alias annotation adds an additional hostname to the same NGINX server block. The F5 NGINX Ingress Controller does not have an equivalent annotation — instead, create a separate VirtualServer resource for each hostname, all pointing to the same backend service. | |
ConfigMap server-tokens |
nginx.org/server-tokens |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The Community controller configures server tokens via ConfigMap only. The F5 NGINX Ingress Controller provides a per-Ingress annotation.
| |
| No direct equivalent (automatic with HTTP/1.1) | nginx.org/websocket-services |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The Community controller handles WebSocket upgrades automatically. The F5 NGINX Ingress Controller provides an explicit annotation to enable WebSocket support for specific services.
| |
| No direct equivalent | nginx.org/listen-ports / nginx.org/listen-ports-ssl |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: These annotations configure custom HTTP and HTTPS listen ports for the Ingress resource. Useful when the controller needs to listen on non-standard ports.
| |
| No direct equivalent | nginx.org/mergeable-ingress-type |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: Mergeable Ingress types allow splitting configuration across multiple Ingress resources for the same host. The
master handles server-level settings while minion resources define individual routes. | |
| No direct equivalent | nginx.org/proxy-set-headers |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: References a ConfigMap containing header key-value pairs that will be added to proxied requests. The annotation value is the ConfigMap name.
| |
| No direct equivalent | nginx.org/http-redirect-code (used with nginx.org/redirect-to-https) |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: Customizes the HTTP redirect status code used when redirecting to HTTPS (default: 301). Common values: 301 (permanent), 302 (temporary), 307 (temporary, preserves method), 308 (permanent, preserves method).
| |
nginx.org/listen-ports and nginx.org/listen-ports-ssl configure custom HTTP/HTTPS ports. nginx.org/mergeable-ingress-type enables master/minion Ingress merging for shared server-level config. nginx.org/proxy-set-headers sets custom proxy headers. nginx.org/http-redirect-code customizes the HTTP redirect status code (default: 301).ModSecurity / WAF
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/enable-modsecuritynginx.ingress.kubernetes.io/enable-owasp-core-rulesnginx.ingress.kubernetes.io/modsecurity-snippetnginx.ingress.kubernetes.io/modsecurity-transaction-id |
No direct replacement (OSS) — see WAF (Plus) |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNo OSS Equivalent: The F5 NGINX Ingress Controller does not include ModSecurity or any built-in WAF module. For WAF capabilities, F5 WAF for NGINX is available with NGINX Plus — see the WAF section in Plus Mappings for migration examples.
Note: The community controller's ModSecurity support relies on a third-party module compiled into the controller image — it is not a native Kubernetes-integrated WAF solution. Neither controller provides an open-source WAF alternative.
| |
Passive Health Checks
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
ConfigMap upstream-fail-timeoutConfigMap upstream-max-fails |
VirtualServer CRD upstreams[].fail-timeout, upstreams[].max-fails— or —nginx.org/fail-timeoutnginx.org/max-fails |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community controller configures passive health checks globally via ConfigMap keys. The F5 NGINX Ingress Controller uses per-Ingress annotations (
nginx.org/max-fails, nginx.org/fail-timeout), giving you finer-grained control. The proxy-next-upstream annotations (see Proxy Settings) complement passive health checks by controlling retry behavior when an upstream fails.Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The VirtualServer CRD allows passive health check settings per upstream. For active health checks that proactively probe endpoints, see Active Health Checks in Plus Mappings.
| |
Proxy Settings
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/proxy-next-upstreamnginx.ingress.kubernetes.io/proxy-next-upstream-timeoutnginx.ingress.kubernetes.io/proxy-next-upstream-tries |
VirtualServer CRD upstreams[].next-upstream, upstreams[].next-upstream-timeout, upstreams[].next-upstream-tries— or —nginx.org/proxy-next-upstreamnginx.org/proxy-next-upstream-timeoutnginx.org/proxy-next-upstream-tries |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Rate Limiting
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/limit-burst-multipliernginx.ingress.kubernetes.io/limit-connectionsnginx.ingress.kubernetes.io/limit-ratenginx.ingress.kubernetes.io/limit-rate-afternginx.ingress.kubernetes.io/limit-rpmnginx.ingress.kubernetes.io/limit-rpsnginx.ingress.kubernetes.io/limit-whitelist |
Policy CRD rateLimit— or —nginx.org/limit-req-ratenginx.org/limit-req-keynginx.org/limit-req-burstnginx.org/limit-req-delaynginx.org/limit-req-no-delaynginx.org/limit-req-zone-sizenginx.org/limit-req-reject-codenginx.org/limit-req-log-levelnginx.org/limit-req-dry-runnginx.org/limit-req-scalenginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerAdditional rate limiting annotations:
nginx.org/limit-req-key (default: ${binary_remote_addr}), nginx.org/limit-req-zone-size, nginx.org/limit-req-no-delay, nginx.org/limit-req-dry-run, nginx.org/limit-req-log-level, nginx.org/limit-req-reject-code (default: 429), nginx.org/limit-req-scale (divides rate by pod count for consistency during autoscaling).Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The rateLimit Policy CRD covers
limit-rps and limit-burst-multiplier. The community annotations limit-connections, limit-rate, limit-rate-after, limit-rpm, and limit-whitelist have no Policy CRD equivalents — use location-snippets for those (see the Annotation Approach). | |
Redirects
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/from-to-www-redirectnginx.ingress.kubernetes.io/permanent-redirectnginx.ingress.kubernetes.io/permanent-redirect-codenginx.ingress.kubernetes.io/temporal-redirectnginx.ingress.kubernetes.io/temporal-redirect-code |
VirtualServer CRD action.redirect |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Rewrites
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/app-rootnginx.ingress.kubernetes.io/rewrite-targetnginx.ingress.kubernetes.io/use-regex |
VirtualServer CRD rewritePath— or —nginx.org/rewritesnginx.org/rewrite-targetnginx.org/path-regexnginx.org/app-root |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-redirect-fromnginx.ingress.kubernetes.io/proxy-redirect-to |
VirtualServer CRD server-snippets— or —ConfigMap or nginx.org/server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller also supports a
proxy-redirect ConfigMap key for global proxy redirect behavior. Use server-snippets for per-Ingress control. | |
nginx.ingress.kubernetes.io/proxy-cookie-domainnginx.ingress.kubernetes.io/proxy-cookie-path |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The F5 NGINX Ingress Controller does not have dedicated annotations for proxy cookie rewriting. Use
location-snippets to configure proxy_cookie_domain and proxy_cookie_path directives. | |
Route Delegation
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
| No direct equivalent | VirtualServerRoute CRD routes[].route |
Tip: This feature requires CRDs. See Installing CRDs for Helm and manifest installation instructions.
Note: The community controller has no equivalent for cross-namespace route delegation. VirtualServerRoute allows different teams to manage their own routing rules while a central VirtualServer controls the domain.
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
SSL/TLS
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/backend-protocol |
VirtualServer CRD upstreams[].tls.enable, upstreams[].type— or —nginx.org/ssl-services or nginx.org/grpc-services |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: For gRPC backends, use
nginx.org/grpc-services: "my-service" instead.Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: For gRPC backends, use
type: grpc on the upstream instead. For gRPC over TLS, combine both: type: grpc and tls.enable: true. | |
nginx.ingress.kubernetes.io/force-ssl-redirect |
nginx.org/redirect-to-https |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote:
force-ssl-redirect in the Community controller forces HTTPS redirect even without a TLS certificate. Use nginx.org/redirect-to-https for similar behavior. | |
nginx.ingress.kubernetes.io/ssl-ciphers |
nginx.org/ssl-ciphers |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers |
nginx.org/ssl-prefer-server-ciphers |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/ssl-redirect |
nginx.org/redirect-to-https or nginx.org/ssl-redirect |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerImportant distinction:
| |
nginx.ingress.kubernetes.io/ssl-passthrough |
TransportServer CRD TLS_PASSTHROUGH (built-in listener) |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/preserve-trailing-slash |
nginx.org/redirect-to-https |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: This annotation affects SSL redirect behavior in the Community controller. The F5 NGINX Ingress Controller preserves trailing slashes by default in its redirect logic.
| |
TCP/UDP Load Balancing
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/stream-snippetnginx.ingress.kubernetes.io/tcp-services ConfigMapnginx.ingress.kubernetes.io/udp-services ConfigMap |
GlobalConfiguration CRD +TransportServer CRD |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Timeouts
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/proxy-connect-timeout |
VirtualServer CRD upstreams[].connect-timeout— or —nginx.org/proxy-connect-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-read-timeout |
VirtualServer CRD upstreams[].read-timeout— or —nginx.org/proxy-read-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
nginx.ingress.kubernetes.io/proxy-send-timeout |
VirtualServer CRD upstreams[].send-timeout— or —nginx.org/proxy-send-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
Upstream Configuration
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
| No direct equivalent | VirtualServer CRD upstreams[] fields— or —nginx.org/fail-timeoutnginx.org/keepalivenginx.org/max-connsnginx.org/max-failsnginx.org/upstream-zone-size |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: These are F5 NGINX Ingress Controller-only features for fine-tuning upstream behavior. The community controller does not provide per-Ingress control over these settings.
| |
NGINX Plus Mappings
These features require an NGINX Plus subscription and provide enterprise-grade capabilities. Most Plus features use CRD-based configuration—click the expandable rows ▶ to see full examples. All items are annotations unless otherwise indicated with a badge. Community annotations use the nginx.ingress.kubernetes.io/ prefix; F5 NGINX Ingress Controller Plus annotations use the nginx.com/ prefix (or appprotect.f5.com/ for F5 WAF for NGINX).
- Annotation-to-annotation rows ▶: Direct mappings where you change the annotation name/prefix. Click to expand and see before/after Ingress YAML examples.
- CRD-based rows ▶: Annotations that map to a CRD (VirtualServer, Policy, or TransportServer). Click to expand for full CRD examples with installation instructions.
- Grouped annotations: Related annotations that work together are grouped in a single expandable row, showing how they map to a unified configuration.
- F5 NGINX Ingress Controller-only rows: Rows marked No direct equivalent on the left are features unique to the F5 NGINX Ingress Controller with no community equivalent.
API Key Authentication
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
| No direct equivalent | Policy CRD Plus apiKey |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller (Plus) | |
Active Health Checks
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
| No direct equivalent | VirtualServer CRD Plus upstreams[].healthCheck— or —nginx.com/health-checksnginx.com/health-checks-mandatorynginx.com/health-checks-mandatory-queuenginx.com/slow-start |
Note: Active health checks proactively probe upstream endpoints at configurable intervals, rather than waiting for client requests to fail. These require NGINX Plus. For more granular control (custom paths, intervals, status matching), use the VirtualServer CRD approach. For passive health checks (OSS), see Passive Health Checks in OSS Mappings.
Note: The VirtualServer CRD provides the most granular control over active health checks. Active health checks and
slowStart require NGINX Plus. For passive health checks (OSS), see Passive Health Checks in OSS Mappings. | |
JWT Authentication
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
| No direct equivalent | Policy CRD Plus jwt— or —nginx.com/jwt-keynginx.com/jwt-login-urlnginx.com/jwt-realmnginx.com/jwt-token |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller (Plus)Note: The annotation approach requires a Kubernetes Secret containing the JWK. The Policy CRD approach is recommended for new deployments as it provides more granular control including JWKS URI support and key caching.
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller (Plus)Note: The Policy CRD approach is recommended for new deployments. It supports JWKS URIs, key caching, and more granular configuration. The
jwt-login-url annotation does not have a direct Policy CRD field — configure redirect logic separately via VirtualServer errorPages or server-snippets for 401 responses. | |
OIDC Authentication
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/auth-cache-durationnginx.ingress.kubernetes.io/auth-cache-keynginx.ingress.kubernetes.io/auth-methodnginx.ingress.kubernetes.io/auth-proxy-set-headersnginx.ingress.kubernetes.io/auth-request-redirectnginx.ingress.kubernetes.io/auth-response-headersnginx.ingress.kubernetes.io/auth-signinnginx.ingress.kubernetes.io/auth-signin-redirect-paramnginx.ingress.kubernetes.io/auth-url |
Policy CRD Plus oidc |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller (Plus)Note: Native OIDC support eliminates the need for oauth2-proxy sidecar. The community
auth-url/auth-signin pattern uses the auth_request module (typically with oauth2-proxy) and supports any external auth service, not just OIDC. The community annotations auth-cache-duration, auth-cache-key, auth-method, auth-proxy-set-headers, auth-request-redirect, auth-response-headers, and auth-signin-redirect-param have no direct OIDC Policy equivalents — the Policy manages these concerns internally. If you need generic external auth (non-OIDC), use nginx.org/location-snippets with the auth_request directive. | |
nginx.ingress.kubernetes.io/auth-keepalivenginx.ingress.kubernetes.io/auth-keepalive-requestsnginx.ingress.kubernetes.io/auth-keepalive-share-varsnginx.ingress.kubernetes.io/auth-keepalive-timeout |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community controller's
auth-keepalive, auth-keepalive-requests, auth-keepalive-share-vars, and auth-keepalive-timeout annotations configure keepalive connections to the external auth service. The F5 NGINX Ingress Controller doesn't have dedicated auth_request annotations. If using the F5 NGINX Ingress Controller OIDC Policy CRD, keepalive is managed internally. For generic external auth, use nginx.org/location-snippets with the auth_request directive. | |
nginx.ingress.kubernetes.io/auth-snippet |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community
auth-snippet injects custom NGINX directives into the auth subrequest block. Since the F5 NGINX Ingress Controller uses the OIDC Policy CRD for authentication (or location-snippets for generic auth), any custom directives should be included directly in the nginx.org/location-snippets annotation alongside the auth_request directive. | |
nginx.ingress.kubernetes.io/auth-always-set-cookie |
VirtualServer CRD location-snippets— or —nginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community
auth-always-set-cookie ensures Set-Cookie headers from the auth service are forwarded to the client regardless of the response code. The F5 NGINX Ingress Controller's OIDC Policy handles cookies internally. For generic external auth, use nginx.org/location-snippets with auth_request_set to capture and forward cookies. | |
nginx.ingress.kubernetes.io/enable-global-auth |
Not applicable |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community controller supports global external authentication via ConfigMap keys (
global-auth-url, etc.). The enable-global-auth: "false" annotation opts an Ingress out of this global setting. The F5 NGINX Ingress Controller does not have global external auth — authentication is always configured per-resource (via OIDC/JWT Policy CRDs or location-snippets). This annotation can be safely removed during migration. | |
Session Affinity / Sticky Sessions
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/affinity: "cookie"nginx.ingress.kubernetes.io/affinity-modenginx.ingress.kubernetes.io/session-cookie-change-on-failurenginx.ingress.kubernetes.io/session-cookie-conditional-samesite-nonenginx.ingress.kubernetes.io/session-cookie-domainnginx.ingress.kubernetes.io/session-cookie-expiresnginx.ingress.kubernetes.io/session-cookie-max-agenginx.ingress.kubernetes.io/session-cookie-namenginx.ingress.kubernetes.io/session-cookie-pathnginx.ingress.kubernetes.io/session-cookie-samesitenginx.ingress.kubernetes.io/session-cookie-secure |
VirtualServer CRD Plus sessionCookie— or —nginx.com/sticky-cookie-services |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller (Plus)Note: The
nginx.com/sticky-cookie-services annotation provides a simpler way to configure session persistence via Ingress annotations. For more granular control (domain, secure, samesite, httpOnly), use the VirtualServer CRD approach.Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller (Plus)Note: The VirtualServer CRD provides the most granular control over session persistence. Community-specific features
affinity-mode, session-cookie-change-on-failure, and session-cookie-conditional-samesite-none have no direct equivalents in the F5 NGINX Ingress Controller. | |
nginx.ingress.kubernetes.io/affinity-canary-behavior |
VirtualServer CRD Plus matches[] + upstreams[].sessionCookie |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller (Plus)Note: The community controller's
affinity-canary-behavior: "sticky" ensures users routed to canary by session affinity continue to be served by the canary. The F5 NGINX Ingress Controller separates these concerns: canary routing uses VirtualServer matches[], splits[], while session persistence uses the VirtualServer upstreams[].sessionCookie field. The sessionCookie feature requires NGINX Plus. See Session Affinity for more details. | |
WAF (Web Application Firewall)
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
| No direct equivalent — see ModSecurity / WAF (OSS) | Policy CRD Plus waf (F5 WAF for NGINX)— or —appprotect.f5.com/app-protect-enableappprotect.f5.com/app-protect-policyappprotect.f5.com/app-protect-security-log-enableappprotect.f5.com/app-protect-security-logappprotect.f5.com/app-protect-security-log-destination |
Note: The
appprotect.f5.com/ annotations enable F5 WAF for NGINX via Ingress annotations. The Policy CRD approach is recommended for new deployments as it provides more flexibility and reusability.
Note: F5 WAF for NGINX provides enterprise WAF capabilities beyond ModSecurity. The Policy CRD approach allows WAF policies to be shared across multiple VirtualServer routes. For community ModSecurity annotations, see the ModSecurity / WAF section in OSS Mappings.
| |
ConfigMap Mappings
Both the community and F5 NGINX Ingress Controllers use a Kubernetes ConfigMap for global NGINX settings. Many keys share the same name, but some are renamed or have different semantics. The keys listed below are community ConfigMap keys that have an equivalent F5 NGINX Ingress Controller ConfigMap key.
Identical Keys
These keys have the same name and semantics in both controllers. No changes are needed when migrating.
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
proxy-connect-timeout |
proxy-connect-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
proxy-read-timeout |
proxy-read-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
proxy-send-timeout |
proxy-send-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
client-body-buffer-size |
client-body-buffer-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
proxy-buffering |
proxy-buffering |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
proxy-buffer-size |
proxy-buffer-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
proxy-busy-buffers-size |
proxy-busy-buffers-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
ssl-ciphers |
ssl-ciphers |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
ssl-protocols |
ssl-protocols |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
ssl-redirect |
ssl-redirect |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
hsts |
hsts |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
hsts-max-age |
hsts-max-age |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
hsts-include-subdomains |
hsts-include-subdomains |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
error-log-level |
error-log-level |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
worker-processes |
worker-processes |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
worker-cpu-affinity |
worker-cpu-affinity |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
worker-shutdown-timeout |
worker-shutdown-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
server-tokens |
server-tokens |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
map-hash-bucket-size |
map-hash-bucket-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
variables-hash-bucket-size |
variables-hash-bucket-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
variables-hash-max-size |
variables-hash-max-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
otel-service-name |
otel-service-name |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
Proxy & Buffering
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
proxy-body-size |
client-max-body-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: Both keys map to the NGINX
client_max_body_size directive. The F5 NGINX Ingress Controller uses the NGINX-native naming convention. | |
proxy-buffers-number |
proxy-buffers |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community key takes just a number (buffer count). The F5 NGINX Ingress Controller key takes the full NGINX
proxy_buffers format: "number size" (e.g., "4 8k"). | |
SSL/TLS
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
ssl-dh-param |
ssl-dhparam-file |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community key references a Kubernetes secret name, while the F5 NGINX Ingress Controller key expects a file path to the DH parameters file mounted into the pod.
| |
force-ssl-redirect |
redirect-to-https |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community controller uses an
X-Forwarded-Proto header check to determine whether to redirect. The F5 NGINX Ingress Controller performs a direct HTTP-to-HTTPS redirect. | |
hsts-preload |
(included automatically) |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The F5 NGINX Ingress Controller's
hsts: "true" includes the preload directive by default. There is no separate hsts-preload key — just enable hsts. | |
Logging
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
disable-access-log |
access-log-off |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
log-format-upstream |
log-format |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
log-format-stream |
stream-log-format |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The word order is swapped: community uses
log-format-stream, while the F5 NGINX Ingress Controller uses stream-log-format. | |
log-format-escape-jsonlog-format-escape-none |
log-format-escaping |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community controller uses separate boolean keys (
log-format-escape-json and log-format-escape-none). The F5 NGINX Ingress Controller uses a single key with a string value: "json", "default", or "none". | |
Worker & Performance
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
max-worker-connections |
worker-connections |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
max-worker-open-files |
worker-rlimit-nofile |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
Upstream & Load Balancing
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
upstream-keepalive-connections |
keepalive |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
load-balance |
lb-method |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community controller defaults to
round_robin and supports methods like ewma and least_conn. The F5 NGINX Ingress Controller defaults to random two least_conn and uses standard NGINX load balancing method names. | |
Keepalive & Timeouts
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
keep-alive |
keepalive-timeout |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: Both map to the NGINX
keepalive_timeout directive. The F5 NGINX Ingress Controller key uses the NGINX-native name and expects a time unit suffix (e.g., "75s"). | |
keep-alive-requests |
keepalive-requests |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
Server & Hash Configuration
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
server-name-hash-max-size |
server-names-hash-max-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: Subtle difference: the community uses
server-name-hash-max-size and server-name-hash-bucket-size (singular "name"), while the F5 NGINX Ingress Controller uses server-names-hash-max-size and server-names-hash-bucket-size (plural "names") matching the NGINX directives. | |
server-name-hash-bucket-size |
server-names-hash-bucket-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
Headers
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
hide-headers |
proxy-hide-headers |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
proxy-real-ip-cidr |
set-real-ip-from |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: Both map to the NGINX
set_real_ip_from directive. The F5 NGINX Ingress Controller key uses the NGINX-native naming convention. | |
Protocol
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
use-http2 |
http2 |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
use-proxy-protocol |
proxy-protocol |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
Snippets
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
main-snippethttp-snippetserver-snippetlocation-snippetstream-snippet |
main-snippetshttp-snippetsserver-snippetslocation-snippetsstream-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: All snippet keys change from singular to plural:
main-snippet → main-snippets, http-snippet → http-snippets, server-snippet → server-snippets, location-snippet → location-snippets, stream-snippet → stream-snippets. | |
OpenTelemetry
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
enable-opentelemetry |
otel-trace-in-http |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
otlp-collector-hostotlp-collector-port |
otel-exporter-endpoint |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community controller uses separate keys for host and port. The F5 NGINX Ingress Controller combines them into a single endpoint URL.
| |