NGINX Ingress Migration Tool
kubernetes/ingress-nginx project has reached end of maintenance. v1.15.1 (March 19, 2026) is the final release — 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
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.
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
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.5.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.4.1/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
Additional Resources
kubernetes/ingress-nginx project has reached end of maintenance. v1.15.1 (March 19, 2026) is the final release — 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 has reached end of maintenance. v1.15.1 (March 19, 2026) is the final release — 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/ |
| ConfigMap Name | ingress-nginx-controller | nginx-config |
| CRD Support | None | VirtualServer, VirtualServerRoute, Policy, TransportServer, GlobalConfiguration |
| NGINX Plus Support | No | Yes (with nginx.com/ annotations) |
accessControl, cors) can now be referenced directly from Ingress resources using the nginx.org/policies annotation — no VirtualServer required. This is the recommended migration path for features that support it. Look for the (Recommended) tab in the mapping examples.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 + nginx.org/policies— or —Policy CRD accessControl + VirtualServer policies[] |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNew in v5.4.0: AccessControl policies can now be referenced directly from Ingress resources using the
nginx.org/policies annotation. This is the simplest migration path — you stay on Ingress resources.Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The VirtualServer approach has been available since before v5.4.0. Use this if you are already migrating to VirtualServer resources for other reasons (e.g., advanced routing, traffic splitting).
| |
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-realmnginx.org/basic-auth-secret |
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[] + VirtualServer CRD 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 |
Policy CRD cors + nginx.org/policies— or —VirtualServer CRD responseHeaders— or —nginx.org/server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller — Policy CRDNew in v5.4.0: The CORS Policy CRD is the recommended migration path. Create a reusable Policy and reference it via
nginx.org/policies on Ingress or VirtualServer.Kubernetes 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. | |
Deprecated
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/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. | |
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 | |
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.
| |
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 | |
| No direct equivalent | nginx.org/proxy-set-headers |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote:
nginx.org/proxy-set-headers requires two resources: (1) the annotation on the Ingress, referencing a ConfigMap name, and (2) the ConfigMap itself containing header key-value pairs. Headers defined in the ConfigMap are added to all proxied requests for that Ingress. The ConfigMap must be in the same namespace as the Ingress resource. | |
HSTS
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
ConfigMap hstsConfigMap hsts-include-subdomainsConfigMap hsts-max-ageConfigMap hsts-preload |
nginx.org/hstsnginx.org/hsts-include-subdomainsnginx.org/hsts-max-age |
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. The F5 NGINX Ingress Controller's
nginx.org/hsts annotation includes the preload directive by default — there is no separate equivalent of the community hsts-preload ConfigMap key. | |
| No direct equivalent | nginx.org/hsts-behind-proxy |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote:
nginx.org/hsts-behind-proxy controls whether HSTS headers are added when NGINX sits behind a proxy or load balancer. When true, HSTS headers are added regardless of the connection protocol. This is an NIC-only feature with no community controller equivalent. | |
Ingress Configuration
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
| 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. | |
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, random two, and random two least_conn (NGINX Plus adds least_time variants). The community controller's ewma method is not supported — the closest equivalent is least_conn. 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. | |
Logging
| 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. | |
Request Mirroring
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/mirror-targetnginx.ingress.kubernetes.io/mirror-request-bodynginx.ingress.kubernetes.io/mirror-host |
VirtualServer CRD location-snippets / VirtualServer CRD 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 | |
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 | |
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.
| |
OpenTelemetry
enable-opentelemetry, opentelemetry-trust-incoming-span). The F5 NGINX Ingress Controller configures OpenTelemetry globally via ConfigMap — tracing applies to all routes when enabled. Per-Ingress toggling is not supported.| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/enable-opentelemetry |
ConfigMap otel-trace-in-http |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote:
otel-trace-in-http is the direct replacement for enable-opentelemetry. Additional ConfigMap keys: otel-exporter-endpoint (required), otel-service-name, otel-exporter-header-name, otel-exporter-header-value. Unlike the community annotation, this enables tracing globally — not per-Ingress. | |
nginx.ingress.kubernetes.io/opentelemetry-trust-incoming-span |
No direct equivalent (tracing is global-only) |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: The community controller's
opentelemetry-trust-incoming-span enables per-Ingress control over whether to trust incoming trace context (W3C Trace Context propagation). The F5 NGINX Ingress Controller does not have a per-Ingress equivalent — when tracing is enabled via ConfigMap, incoming trace context is always propagated. This annotation can be safely removed during migration. | |
| No direct equivalent | ConfigMap otel-exporter-endpointConfigMap otel-exporter-header-nameConfigMap otel-exporter-header-valueConfigMap otel-service-name |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: These ConfigMap keys are NIC-only and configure the OpenTelemetry exporter.
otel-exporter-endpoint is required when tracing is enabled. otel-service-name sets the service name in traces (defaults to nginx-ingress). otel-exporter-header-name and otel-exporter-header-value add custom headers to exporter requests (e.g., for authentication). | |
Passive Health Checks
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
ConfigMap upstream-fail-timeoutConfigMap upstream-max-fails |
VirtualServer CRD upstreams[].fail-timeoutVirtualServer CRD 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-upstreamVirtualServer CRD upstreams[].next-upstream-timeoutVirtualServer CRD 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 ControllerNew in v5.4.0: The
nginx.org/proxy-next-upstream, nginx.org/proxy-next-upstream-timeout, and nginx.org/proxy-next-upstream-tries annotations are new. They provide direct 1:1 mappings from the community annotations without requiring a VirtualServer CRD. | |
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. | |
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-burstnginx.org/location-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes 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). | |
ConfigMap limit-req-status-code |
nginx.org/limit-req-reject-code |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress ControllerNote: The community controller sets the rate limit rejection status code globally via ConfigMap. The F5 NGINX Ingress Controller sets it per-Ingress via the
nginx.org/limit-req-reject-code annotation (default: 429). | |
| No direct equivalent | nginx.org/limit-req-delaynginx.org/limit-req-dry-runnginx.org/limit-req-keynginx.org/limit-req-log-levelnginx.org/limit-req-no-delaynginx.org/limit-req-reject-codenginx.org/limit-req-scalenginx.org/limit-req-zone-size |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: These NIC-only annotations provide fine-grained rate limiting control.
limit-req-key customizes the rate limiting key (default: ${binary_remote_addr}). limit-req-scale divides the rate by pod count for consistency during autoscaling. limit-req-reject-code sets the response code for rejected requests (default: 429). limit-req-dry-run enables logging without enforcing limits. | |
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/app-rootnginx.org/path-regexnginx.org/rewrite-target |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNew in v5.4.0: The
nginx.org/app-root annotation is new. It provides a direct 1:1 mapping from the community app-root annotation without requiring a VirtualServer CRD. | |
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. | |
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. | |
| No direct equivalent | nginx.org/rewrites (per-service URL rewriting) |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote:
nginx.org/rewrites enables per-service URL rewriting within a single Ingress resource. Each semicolon-separated entry specifies a service name and its rewrite path. This is an NIC-only feature with no community controller equivalent. | |
Route Delegation
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
nginx.ingress.kubernetes.io/server-alias |
VirtualServer CRD one resource per hostname— or —nginx.org/server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes 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. Alternatively, use nginx.org/server-snippets to add additional server_name directives. | |
| 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.enableVirtualServer CRD upstreams[].type— or —nginx.org/ssl-servicesnginx.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/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.
| |
nginx.ingress.kubernetes.io/ssl-ciphers |
nginx.org/ssl-ciphers |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress Controller | |
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/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 / nginx.org/ssl-redirect + nginx.org/http-redirect-code: "308"— or —VirtualServer CRD tls.redirect.code: 308 |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerKubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerImportant distinction:
Note: The community controller's
ssl-redirect defaults to a 308 Permanent Redirect, which preserves the original request method and body. The F5 NGINX Ingress Controller defaults to 301, which clients may downgrade to GET and drop the request body. To match the community behavior exactly, set nginx.org/http-redirect-code: "308" on the Ingress, or tls.redirect.code: 308 on the VirtualServer.New in v5.4.0: The
nginx.org/ssl-redirect and nginx.org/http-redirect-code annotations are new. Previously, only nginx.org/redirect-to-https was available, with a fixed 301 response code. Use ssl-redirect as the direct 1:1 mapping from the community annotation. | |
| No direct equivalent | nginx.org/http-redirect-code (used with nginx.org/redirect-to-https) |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNew in v5.4.0: Customizes the HTTP redirect status code used when redirecting to HTTPS (default: 301). Available as both a per-Ingress annotation and a global ConfigMap key (
http-redirect-code). Common values: 301 (permanent), 302 (temporary), 307 (temporary, preserves method), 308 (permanent, preserves method). | |
| 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.
| |
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.
| |
| 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.
| |
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 sessionCookie— or —nginx.com/sticky-cookie-services |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: 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 ControllerNew in v5.4.0: Session persistence via
sessionCookie is now available in both NGINX OSS and NGINX Plus. Community-specific features affinity-mode, session-cookie-change-on-failure, and session-cookie-conditional-samesite-none have no direct equivalents. | |
nginx.ingress.kubernetes.io/affinity-canary-behavior |
VirtualServer CRD matches[] + VirtualServer CRD upstreams[].sessionCookie |
Kubernetes Ingress NGINX (Ingress-NGINX)F5 NGINX Ingress ControllerNote: 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 is available in both NGINX OSS and NGINX Plus. | |
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-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/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/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. | |
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.
ingress-nginx-controller. The F5 NGINX Ingress Controller uses nginx-config by default (configurable via --configmap flag). Remember to update the ConfigMap name in your deployment.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 |
|---|---|
client-body-buffer-size |
client-body-buffer-size |
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 | |
hsts |
hsts |
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 | |
hsts-max-age |
hsts-max-age |
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 | |
otel-service-name |
otel-service-name |
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-buffering |
proxy-buffering |
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 | |
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 | |
server-tokens |
server-tokens |
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 | |
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 | |
worker-cpu-affinity |
worker-cpu-affinity |
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-shutdown-timeout |
worker-shutdown-timeout |
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 |
|---|---|
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. | |
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.
| |
| No direct equivalent | http-redirect-code |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNew in v5.4.0: The
http-redirect-code ConfigMap key sets the global HTTP redirect status code used when redirecting to HTTPS (default: 301). Can also be set per-Ingress via the nginx.org/http-redirect-code annotation. Common values: 301 (permanent), 302 (temporary), 307 (temporary, preserves method), 308 (permanent, preserves method). | |
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-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". | |
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-upstream |
log-format |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
Network / Real IP
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
proxy-real-ip-cidr |
set-real-ip-from |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community controller uses
proxy-real-ip-cidr and use-forwarded-headers. The F5 NGINX Ingress Controller uses the NGINX-native set-real-ip-from, real-ip-header, and real-ip-recursive ConfigMap keys. | |
use-forwarded-headers |
real-ip-header |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
use-proxy-protocol |
proxy-protocol |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: When enabling PROXY protocol, also configure
set-real-ip-from and real-ip-header to properly extract client IPs from the PROXY protocol header. | |
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 |
|---|---|
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. | |
upstream-keepalive-connections |
keepalive |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
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-bucket-size |
server-names-hash-bucket-size |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
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. | |
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.
| |
Snippet-Based Keys
These community ConfigMap keys have no direct equivalent in the F5 NGINX Ingress Controller. Use main-snippets, http-snippets, or server-snippets in the NIC ConfigMap to inject the equivalent NGINX directives.
| Kubernetes Ingress NGINX (Ingress-NGINX) | F5 NGINX Ingress Controller |
|---|---|
access-log-path |
http-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
custom-http-errors |
server-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMapNote: The community controller integrates with a default backend for custom error pages. The NIC requires manual
error_page directives via snippets, typically combined with a custom error backend. | |
enable-brotli |
http-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |
error-log-path |
main-snippets |
Kubernetes Ingress NGINX (Ingress-NGINX) ConfigMapF5 NGINX Ingress Controller ConfigMap | |