Skip to main content

Documentation Index

Fetch the complete documentation index at: https://ryvn.ai/docs/llms.txt

Use this file to discover all available pages before exploring further.

Ryvn is upgrading its networking stack. Ingress NGINX is being retired, and a new foundation is taking its place. If you use Ingress resources today, most of them will keep working without changes. This applies to Ryvn-managed ingress classes: external-nginx and internal-nginx. If your workload uses a different ingress class, this guide doesn’t apply to it. This is also the beginning of a bigger shift in how networking works on Ryvn. Instead of writing NGINX annotations or raw Kubernetes resources, you’ll configure routing, timeouts, CORS, and access control through Ryvn-native fields directly on your Service/Installation.

Why

The Kubernetes community retired ingress-nginx in March 2026. Staying on an unmaintained ingress controller means falling behind on security patches and accumulating tech debt that only gets harder to pay down. There’s no drop-in replacement for ingress-nginx, and we didn’t want one. We’re using this to move networking config out of NGINX annotations and into Ryvn itself. That gives us room to ship features a generic ingress controller can’t support.

Does this affect you?

Find your setup in the table below.
Service typeNginx annotationsWhat to do
ServerNoNo action. Stay tuned for Ryvn-native networking features.
ServerYesReview the annotation support matrix.
Helm ChartNoReview the Helm Chart notes below.
Helm ChartYesReview the annotation support matrix and the Helm Chart notes below.
We’ll reach out before your environment migrates if we see anything unsupported in your rendered resources.

Server services with custom annotations

If you’ve set anything under networking settings using nginx.ingress.kubernetes.io/* annotations, check the annotation support matrix. Some common annotations still work through a compatibility layer. For the long tail of NGINX-specific knobs beyond that, we’ve chosen not to carry them forward. They’re rarely used on our platform, and supporting them would keep you tied to legacy technology we’re replacing with something better. If you’re using something that isn’t supported, we’ll reach out before your environment migrates and work through it with you.

Helm Chart services

With Helm Chart services, the chart controls the Ingress resources it renders, including paths, host matching, pathType, and annotations. You often don’t write those directly. Two things to check on the rendered Ingress: Annotations. If the chart sets nginx.ingress.kubernetes.io/* annotations, review the annotation support matrix. If the chart depends on something unsupported, you may need to override values, swap chart versions, or migrate to a Ryvn-native alternative. Spec-level features. A few Ingress spec fields aren’t supported on the compatibility layer:
  • backend.resource — not supported. Only backend.service works as a backend target.
  • spec.defaultBackend — only catches unmatched paths for hosts listed in your spec.rules. On ingress-nginx it also caught requests for unknown hosts; on the compatibility layer those are rejected instead.
  • pathType: ImplementationSpecific — NGINX treated this as regex-capable by default. On the compatibility layer, it’s treated as a literal Prefix match. If you want regex matching, set nginx.ingress.kubernetes.io/use-regex: "true" explicitly.

Annotation support

Previously, Ryvn allowed advanced routing configuration through nginx.ingress.kubernetes.io/* annotations on your Ingress resources. Going forward, raw NGINX annotations are no longer the way to configure networking on Ryvn. We’ll be gradually replacing them with platform-level features that don’t require you to know which proxy is running underneath. During the transition, we run a compatibility layer that still supports the most commonly used annotations.

Supported

These annotations work through the compatibility layer:
AnnotationBehavior
nginx.ingress.kubernetes.io/force-ssl-redirect / nginx.ingress.kubernetes.io/ssl-redirectHTTPS redirect. See HTTPS redirects and trailing slashes if your app treats /path and /path/ differently.
nginx.ingress.kubernetes.io/proxy-read-timeout / nginx.ingress.kubernetes.io/proxy-send-timeoutBoth merge into one request deadline. If both are set, the larger value wins. See timeouts.
nginx.ingress.kubernetes.io/proxy-connect-timeoutConnection timeout to backend. Defaults to 60s even without the annotation. Applied per backend service, not per ingress. See timeouts.
nginx.ingress.kubernetes.io/backend-protocolHTTP and GRPC are supported. Other values (HTTPS, GRPCS, FCGI) are not; see unsupported protocols.
nginx.ingress.kubernetes.io/rewrite-targetLiteral path rewrites only (e.g., /). Capture groups like /$1 are not supported; see capture-group rewrites.
nginx.ingress.kubernetes.io/use-regexRegex path matching on Ingress rules.
nginx.ingress.kubernetes.io/whitelist-source-range / nginx.ingress.kubernetes.io/allowlist-source-rangeIP allowlist. Requests from outside the listed CIDRs are blocked. Both annotation names work; if both are set, they must have the same value. Not compatible with use-regex or rewrite-target on the same Ingress; combining them will be rejected.
nginx.ingress.kubernetes.io/denylist-source-rangeIP denylist. Requests from the listed CIDRs are blocked. Not compatible with use-regex or rewrite-target on the same Ingress; combining them will be rejected.
nginx.ingress.kubernetes.io/use-forwarded-headersAlready handled by the compatibility layer. Safe to leave in place.
nginx.ingress.kubernetes.io/proxy-http-versionHTTP/1.1 is already the default. Safe to leave in place.
nginx.ingress.kubernetes.io/x-forwarded-protoSet automatically on TLS termination. Safe to leave in place.

HTTPS redirects and trailing slashes

By default, ingress-nginx strips the trailing slash from the path when it redirects HTTP to HTTPS. The compatibility layer keeps the requested path for HTTPS redirects.
Requestingress-nginx (default)Compatibility layer
http://app.example.com/docs/https://app.example.com/docshttps://app.example.com/docs/
http://app.example.com/docs/page/https://app.example.com/docs/pagehttps://app.example.com/docs/page/
This only affects requests that already end in /. Paths without a trailing slash redirect to the same URL on both. Slash-add redirects still work the same way: if your Ingress path is /docs/, a request to /docs redirects to /docs/. If your app treats /docs and /docs/ as different routes, test both before you migrate.

Snippets

This applies only if your Helm chart or Server service sets snippet annotations. Snippet annotations let you inject arbitrary NGINX config into your Ingress. Moving forward, we won’t be accepting them on Ryvn-managed ingress classes. Arbitrary directives are a security risk, and they make routing behavior unpredictable and hard to reproduce across environments. On our platform, snippets have mostly been used for configuring a WAF in front of the app and injecting headers into upstream requests. Both are things we want to provide as Ryvn-native features, so you don’t have to maintain custom NGINX config yourself. These annotations will be rejected:
  • nginx.ingress.kubernetes.io/configuration-snippet
  • nginx.ingress.kubernetes.io/server-snippet
  • nginx.ingress.kubernetes.io/auth-snippet
  • nginx.ingress.kubernetes.io/stream-snippet
You won’t be able to create Ingress resources that set these on a Ryvn-managed ingress class. If one of these is a blocker for you, send us a message and we’ll figure out an alternative.

Basic and external auth

Previously, you could put HTTP basic auth on an Ingress or delegate authentication to an external service through NGINX annotations: Basic auth:
  • nginx.ingress.kubernetes.io/auth-type
  • nginx.ingress.kubernetes.io/auth-secret
  • nginx.ingress.kubernetes.io/auth-secret-type
  • nginx.ingress.kubernetes.io/auth-realm
External auth:
  • nginx.ingress.kubernetes.io/auth-url
  • nginx.ingress.kubernetes.io/auth-signin
  • nginx.ingress.kubernetes.io/auth-signin-redirect-param
  • nginx.ingress.kubernetes.io/auth-response-headers
  • nginx.ingress.kubernetes.io/auth-request-redirect
  • nginx.ingress.kubernetes.io/auth-method
  • nginx.ingress.kubernetes.io/auth-proxy-set-headers
Global auth:
  • nginx.ingress.kubernetes.io/enable-global-auth
  • nginx.ingress.kubernetes.io/satisfy
These annotations will be rejected on Ryvn-managed ingress classes — Ingress resources that set them won’t be admitted. Ryvn-native auth support is coming soon, including for apps that don’t ship built-in auth. In the meantime, we can help you set up an auth proxy (like OAuth2 Proxy) in front of your service via a Ryvn blueprint. Reach out and we’ll wire it up.

Client certificate auth (mTLS)

Previously, you could turn on client certificate verification on an Ingress by setting a handful of NGINX-specific annotations:
  • nginx.ingress.kubernetes.io/auth-tls-secret
  • nginx.ingress.kubernetes.io/auth-tls-verify-client
  • nginx.ingress.kubernetes.io/auth-tls-verify-depth
  • nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream
  • nginx.ingress.kubernetes.io/auth-tls-match-cn
  • nginx.ingress.kubernetes.io/auth-tls-error-page
These annotations will be rejected on Ryvn-managed ingress classes — Ingress resources that set them won’t be admitted. We’re moving mTLS into Ryvn itself — you’ll be able to turn it on directly for your Service Installation, without writing NGINX annotations. Coming soon. Until then, per-Ingress mTLS isn’t available. If you have a workload that needs client cert verification in the meantime, get in touch and we’ll work through it with you.

WAF (ModSecurity)

This applies only if your Helm chart or Server service sets ModSecurity annotations. Previously, you could turn on a ModSecurity WAF in front of your app through NGINX annotations on your Ingress:
  • nginx.ingress.kubernetes.io/enable-modsecurity
  • nginx.ingress.kubernetes.io/enable-owasp-core-rules
  • nginx.ingress.kubernetes.io/modsecurity-snippet
  • nginx.ingress.kubernetes.io/modsecurity-transaction-id
These annotations will be rejected on Ryvn-managed ingress classes — Ingress resources that set them won’t be admitted. WAF isn’t a Ryvn-native feature yet either. If your workload relies on a WAF today, we’ll work out an alternative with you case-by-case before migrating your environment.

Body size limits

On ingress-nginx, nginx.ingress.kubernetes.io/proxy-body-size guarded your app from oversized requests — the proxy rejected anything over the limit before it ever reached your backend. This was often used for things like capping file upload size, protecting against accidental giant JSON payloads, or shielding internal endpoints from abuse. This is no longer supported through the annotation. The compatibility layer doesn’t enforce a request body size limit by default; bodies stream through to your backend. If any part of your app was relying on the proxy to reject large requests for you, that path now needs to be handled in the app. The good news is that most common frameworks already have a built-in way to enforce this. Set the limit in your app config and you’re good:
  • Express.jslimit option on express.json() / express.urlencoded() (default 100kb).
  • Next.js (Pages Router API routes)config.api.bodyParser.sizeLimit. App Router Route Handlers have no equivalent; cap the body yourself as you read it.
  • DjangoDATA_UPLOAD_MAX_MEMORY_SIZE (and FILE_UPLOAD_MAX_MEMORY_SIZE for uploads).
  • Flaskapp.config['MAX_CONTENT_LENGTH'].
  • Spring Bootspring.servlet.multipart.max-request-size and max-file-size.
  • Go net/http — wrap the request body with http.MaxBytesReader.
If this is a blocker for you and you want body size limits as a Ryvn-native feature, let us know and we’ll figure it out for you.

Buffering

The compatibility layer streams requests and responses straight through to your app instead of holding them in an intermediate buffer. ingress-nginx buffer-tuning annotations don’t apply. For most apps this is invisible or faster. You’re more likely to notice a change if your backend was relying on NGINX to absorb traffic on its behalf. Common examples:
  • Legacy servers that stall when a request body arrives slowly, because they assume the full request has already been collected.
  • Apps that emit very large response headers.
  • Backends that can’t cleanly handle a partial request body or response stream.
If any of that applies, handle the streaming data in your app or run a buffering layer closer to the backend. If this is a blocker for your workload, ping us and we’ll work through it with you. Annotations that no longer take effect:
  • nginx.ingress.kubernetes.io/proxy-buffering
  • nginx.ingress.kubernetes.io/proxy-buffer-size
  • nginx.ingress.kubernetes.io/proxy-buffers-number
  • nginx.ingress.kubernetes.io/proxy-busy-buffers-size
  • nginx.ingress.kubernetes.io/proxy-busy-buffers
  • nginx.ingress.kubernetes.io/proxy-request-buffering
  • nginx.ingress.kubernetes.io/client-body-buffer-size
  • nginx.ingress.kubernetes.io/large-client-header-buffers

gRPC backend (nginx.ingress.kubernetes.io/grpc-backend)

The legacy nginx.ingress.kubernetes.io/grpc-backend annotation is not supported. Use nginx.ingress.kubernetes.io/backend-protocol: GRPC instead. gRPC ingresses don’t support HTTP-specific annotations. The following are dropped:
  • nginx.ingress.kubernetes.io/proxy-read-timeout
  • nginx.ingress.kubernetes.io/proxy-send-timeout
  • nginx.ingress.kubernetes.io/rewrite-target
  • nginx.ingress.kubernetes.io/use-regex
  • nginx.ingress.kubernetes.io/force-ssl-redirect / nginx.ingress.kubernetes.io/ssl-redirect
If your gRPC service relies on any of these, get in touch before your environment migrates.

Unsupported backend protocols

nginx.ingress.kubernetes.io/backend-protocol supports HTTP and GRPC only. The following values are not supported:
  • HTTPS, GRPCS — TLS origination to the backend
  • AUTO_HTTP, FCGI, and anything else
If you need TLS origination to a backend, reach out and we’ll work through alternatives. nginx.ingress.kubernetes.io/use-http2 is also not the right knob on the compatibility layer — HTTP/2 upgrade is handled automatically where applicable.

Capture-group rewrites

nginx.ingress.kubernetes.io/rewrite-target supports literal values only (e.g. nginx.ingress.kubernetes.io/rewrite-target: /). Capture-group rewrites like /$1 or /$2 are not supported. If you need capture-group behavior, split your routes explicitly into multiple Ingress rules, or use manual gateway resources.

Timeouts

nginx.ingress.kubernetes.io/proxy-read-timeout and nginx.ingress.kubernetes.io/proxy-send-timeout both translate to a single request deadline. If you set both, the larger value wins. NGINX only supports TCP-level timeouts. It treats nginx.ingress.kubernetes.io/proxy-read-timeout as an idle timeout: the timer resets every time the backend sends data. If you have a 60-second read timeout and your backend streams a response, sending a chunk every 45 seconds, NGINX resets the clock on each chunk. The connection stays open indefinitely. The compatibility layer treats the same annotation as an overall request deadline: a total time limit for the request to finish. That same streaming response gets cut off after 60 seconds total, regardless of how much data came through in between. This mostly affects long-lived HTTP connections: SSE, long-polling, large file downloads, or anything where the client waits between response chunks. A value like 86400 (24 hours) still works, but it’s 24 hours from the start of the request, not 24 hours of silence. If your service relies on NGINX’s idle-timeout behavior, plan for this before migration. nginx.ingress.kubernetes.io/proxy-connect-timeout is handled separately. The default is 60s, same as ingress-nginx. If you set a value explicitly, it’s translated as-is. A value of 0 is ignored and falls back to 60s. If multiple ingresses point to the same backend service, set nginx.ingress.kubernetes.io/proxy-connect-timeout consistently on each. Conflicting values are dropped and the backend falls back to the 60s default. Timeout annotations don’t apply to gRPC ingresses. See gRPC backend for the full list of annotations dropped on gRPC routes.

What to do now

Check whether any of your Ingress resources use unsupported annotations. If they do, start planning the migration. We can help. Long-lived connections (SSE, WebSocket, gRPC streaming) are worth a closer look too. Review your timeout values against the new timeout behavior. If you only use standard annotations like nginx.ingress.kubernetes.io/force-ssl-redirect and timeouts, you don’t need to do anything.

Questions?

Reach out through your shared Slack channel or contact support.