Navigating Ingress-NGINX Quirks: What to Know Before Migration

From Michili, the free encyclopedia of technology

Introduction

As announced in November 2025, Kubernetes will retire Ingress-NGINX in March 2026. Despite its widespread use, this Ingress controller harbors surprising defaults and side effects that may be lurking in your cluster right now. This article highlights one such behavior—regex matching quirks—to help you migrate safely and make informed decisions about preserving or adapting these behaviors when moving to Gateway API. The recurring risk is that a seemingly correct translation can cause outages if it doesn’t account for Ingress-NGINX’s unique traits. We assume you have some familiarity with Ingress-NGINX and the Ingress API. Note that Ingress-NGINX (community-maintained) and NGINX Ingress (by F5) are two separate controllers, though both use NGINX as the dataplane.

Navigating Ingress-NGINX Quirks: What to Know Before Migration

The Surprising Regex Behavior

One of the most surprising behaviors is how Ingress-NGINX handles regular expressions in path matching. Suppose you want to route all requests whose path consists of exactly three uppercase letters (like /ABC) to a service. You might create an Ingress with the nginx.ingress.kubernetes.io/use-regex: "true" annotation and a regex pattern /[A-Z]{3}:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: regex-match-ingress
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: regex-match.example.com
    http:
      paths:
      - path: "/[A-Z]{3}"
        pathType: ImplementationSpecific
        backend:
          service:
            name: httpbin
            port:
              number: 8000

However, Ingress-NGINX applies two unexpected twists: regex matches are prefix-based and case-insensitive. This means the controller will route any request whose path starts with any three letters (lowercase or uppercase) to the backend. For example:

curl -sS -H "Host: regex-match.example.com" http://<your-ingress-ip>/uuid

This returns a response from httpbin’s /uuid endpoint, proving the request was routed, even though /uuid does not consist of three uppercase letters. The pattern /[A-Z]{3} became a prefix match for any three alphabetic characters, ignoring case.

Why This Happens

Ingress-NGINX, by design, compiles regex patterns and then uses them as prefix matches on the request path. Additionally, the underlying NGINX location matching treats patterns as case-insensitive unless explicitly configured otherwise. This can lead to unexpected routing—especially if clients send paths like /uuid or /abc/resource—and might cause outages when migrating to a controller that doesn’t have these quirks.

Implications for Migration

When moving from Ingress-NGINX to Gateway API (the recommended successor), you must be aware of these behavioral differences. A direct translation of the above Ingress to an HTTPRoute might look correct but fail if the new implementation uses strict, full-path regex matching.

In Gateway API, you can use an HTTP path match with type: RegularExpression. However, the semantics of regular expression matching are implementation-specific. Popular Envoy-based Gateway API implementations—such as Istio, Envoy Gateway, and Kgateway—perform a full, case-sensitive match by default. So if you blindly copy the Ingress’s pattern, traffic to /uuid will be rejected, breaking existing clients.

Preserving Ingress-NGINX Behavior in Gateway API

To maintain the same prefix-based, case-insensitive regex behavior, you need to adjust your Gateway API configuration. One approach is to use a PathPrefix match combined with a custom filter or to write the regex explicitly to mimic the original behavior. For example, you could create an HTTPRoute that matches any three-letter path prefix and then use a rewrite filter to ensure correct routing. Always consult your Gateway API implementation’s documentation for the most reliable method.

Here’s an example of how you might preserve the prefix and case-insensitive behavior using a PathPrefix match with a three-character segment:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: regex-migration-route
spec:
  parentRefs:
  - name: my-gateway
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: "/"
    filters:
    - type: URLRewrite
      urlRewrite:
        path:
          type: ReplacePrefixMatch
          replacePrefixMatch: "/"
    backendRefs:
    - name: httpbin
      port: 8000

Note: This simplified example may need additional regex-based matching via a custom filter depending on your implementation.

Conclusion

The regex matching quirk is just one of five surprising behaviors you need to know before migrating from Ingress-NGINX. Each behavior shares the same risk: a direct translation can cause outages if you don’t account for Ingress-NGINX’s defaults. By understanding these quirks and adapting your Gateway API configurations accordingly, you can ensure a smooth transition. Always test your new routing rules thoroughly before cutting over.

Stay tuned for future articles covering the other four behaviors, and begin your migration planning now—March 2026 will be here sooner than you think.