TLS passthrough and SNI routing in Apache APISIX

APISIX can forward encrypted streams untouched and pick the upstream from the SNI in the ClientHello. This page covers how to configure it, where it mixes with termination, and which gateway features you lose.

On this page

When TLS passthrough and SNI routing in Apache APISIX fit your design

If you need one edge address to serve several backends that each hold their own certificates or require mutual TLS, TLS passthrough lets Apache APISIX choose the backend by SNI without decrypting the traffic. The main trade-off is that the gateway can only route on what it can read in the ClientHello, so gateway-side authentication, request inspection and TLS-based policies stop applying to those connections. Decide early whether the edge needs to see inside the payload at all, because that answer determines which listener mode you need.

In APISIX, this sits in the stream proxy context, which handles layer 4 traffic on TCP and UDP. With tls_passthrough enabled on a stream route, APISIX forwards the encrypted stream untouched and matches the route on the SNI value from the ClientHello. Wildcard SNI values match as a suffix, so you can map a whole domain to one backend. Compare this with terminating TLS at the gateway, where APISIX holds the certificate, decrypts the request and can apply plugins to the HTTP content. Passthrough keeps certificate ownership with each backend, but it also means the gateway cannot present its own certificate or verify client certificates on those connections.

Confirm three things before you commit. Backends reached over the tls upstream scheme return 503 on a passthrough route, so the upstream must speak plain TCP from APISIX's point of view. Gateway mTLS does not apply, so client identity has to be checked by the backend itself. Stream plugins that inspect payloads cannot read passthrough traffic. Verify these limits against the stream proxy documentation and test them against the exact APISIX version you plan to run, since behavior is defined per release.

Configuration options and when each fits

This table compares the stream route modes and SNI matching choices available on an APISIX stream listener, with the consequence of each choice. Read each row as a decision: find the workload you have, then check the constraint that comes with it before you write the route.

OptionWhen it fitsConsequence to plan for
tls_passthrough routeBackends hold their own certificates and must see the client's TLS session end to endGateway mTLS does not apply and APISIX cannot read the payload
Scheme tls upstreamAPISIX should terminate client TLS and open a TLS connection to the backendPointing a scheme tls upstream at a passthrough route returns 503
Terminated TLS on the same listenerOne port serves both passthrough and terminated services, and each stream route picks its modeStream plugins that inspect payloads only work on terminated routes
Exact SNI entryA single known hostname maps to one backend and the routing table must stay tightEach new hostname needs its own route entry or it will not match
Wildcard SNI entryMany hosts under one domain share a backend pool, such as tenant subdomainsMatches as a suffix, so confirm the pattern does not catch hosts you did not intend
Payload-inspecting stream pluginsYou need to read or transform traffic at layer 4Unavailable on passthrough ports, so move that control to the backend or to a terminated route
Gateway-level authentication and rate limits by request contentPolicy depends on HTTP headers, paths or consumer identityNot possible on passthrough, so use a terminated listener for those controls

Mixing passthrough and termination on one port

A passthrough route forwards the encrypted stream untouched. APISIX reads the server name from the TLS ClientHello, matches the route by SNI, and hands the connection to the upstream without decrypting it. The backend keeps its own certificate and private key, so it is the party that completes the handshake with the client. Gateway mTLS does not apply to these connections, and upstreams configured with the tls scheme return 503 on this path, so the upstream must be defined as a plain stream target that already speaks TLS.

  • Certificate ownership: the backend presents and renews its certificate, so the gateway team does not need to store or rotate that key.
  • Client certificate checks: any mutual TLS happens between the client and the backend, not at APISIX.
  • Payload plugins: stream plugins that read the payload cannot inspect this traffic, so authentication and filtering must live in the backend.
  • Logging depth: you see the SNI, connection metadata and byte counts, but not request paths, headers or methods.
  • Upstream definition: the upstream entry must match a stream target and must not depend on gateway-side TLS settings.

Before publishing a passthrough hostname, confirm that the backend serves a certificate valid for that exact name and that the route configuration matches the upstream behavior of your APISIX release.

Setting up passthrough routes step by step

This sequence takes an APISIX stream listener from configuration to verified passthrough, so encrypted connections reach the right backend by server name without the gateway ever decrypting them. Each step ends with a check you can run before moving on.

  1. Confirm stream mode and listener settings

    Your platform engineer checks that the APISIX deployment has stream proxy enabled in its static configuration and that the chosen listening port is free on the gateway nodes and allowed by the network path from clients. Confirm the exact configuration keys for the APISIX version you run against the stream proxy documentation, since the layout of these settings has changed between releases. Done when the gateway starts cleanly with stream mode on and a simple TCP check to the listening port connects from a client subnet.

  2. Define the passthrough listener

    Create the stream listener on the chosen port and set tls_passthrough to true for that listener, so APISIX forwards the encrypted stream untouched instead of terminating it. Keep the listener scoped to the traffic it is meant to carry, because every route on it inherits passthrough behavior. Done when the Admin API or your configuration file shows the listener in its saved state and the gateway accepts a connection on that port without returning a certificate of its own.

  3. Add SNI-matched routes to backends

    Create one stream route per hostname, matching on the server name in the TLS ClientHello and pointing at a backend that holds its own certificate for that name. Confirm that each upstream uses a plain TCP target rather than a scheme that expects TLS from the gateway, since passthrough upstreams configured as TLS return errors. Wildcard server names match as a suffix, so write those routes deliberately. Done when each route appears in the configuration with the expected host pattern and upstream address.

  4. Test with a client that sends the expected SNI

    From a client outside the gateway network, connect with a TLS client that sends the server name you configured, using a tool such as OpenSSL's client command with its server name option. Your platform team should observe the certificate presented by the backend, not one issued by the gateway. Repeat for each route. Done when the presented certificate matches the backend for each hostname and the backend logs show the connection arriving.

  5. Verify that unmatched SNI is refused

    Send a connection with a server name that no route covers, and with no server name at all, to confirm the gateway refuses it rather than falling back to a default backend. A default route here would send traffic for unknown names to an unintended service, so this check matters for security review. Done when the connection fails at the gateway and no backend records it.

  6. Record the configuration and the test evidence

    Save the listener and route definitions in version control, along with the test commands, client output and backend logs from the previous steps. Auditors and change reviewers will ask how routing was validated, so keep the results with the change record. Done when the configuration can be reapplied to a clean environment and the test results are attached to the change ticket.

Features you give up when the gateway cannot see the payload

A passthrough route trades visibility for end-to-end encryption. The cards below cover the controls that depend on the gateway reading the request, and the work that moves to the backend or to a different layer when it cannot.

Gateway mTLS does not apply

With tls_passthrough enabled, APISIX forwards the encrypted stream untouched, so it cannot terminate client certificates or enforce client certificate checks on that route. Client authentication has to happen in the backend service, or in a layer that terminates TLS before the gateway. Before you cut over, confirm which identity checks currently run at the gateway and where each one will live afterward.

Stream plugins cannot read payloads

Plugins that inspect traffic content cannot run against passthrough ports. Any policy that depends on reading bytes, such as payload-level filtering or protocol-aware checks on a stream route, has to be removed from the design or relocated. List every stream plugin you planned and mark each one as either metadata-only or content-dependent before you finalize the route layout.

No TLS-level header inspection

The gateway sees only the SNI value from the ClientHello, not HTTP headers, paths or request bodies, because those sit inside the encrypted session. Header-based routing, header rewriting and trust rules for forwarded client identity do not work on these routes. Decide early which routing keys must come from SNI alone and which can move to a terminating listener.

Limited request-level observability

Access logs and metrics on a passthrough route can record connection-level data, such as the SNI name and byte counts, but not the method, path or response status of the inner request. Teams that rely on per-request dashboards or audit trails must confirm that the backend produces those records. Ask your team which log fields and alerts depend on request content, and plan their source before go-live.

WAF and content inspection move backend

Web application firewall rules and content scanning cannot inspect encrypted payloads at the gateway. If your security standard requires inspection of inbound web traffic, that control must run in the backend, on a separate inspection tier that holds the keys, or on a terminating route. Document where each inspection step runs so auditors can trace it.

Scheme tls upstreams return 503

A route that uses the tls scheme for its upstream is not usable on a passthrough route, and requests to it return 503. Confirm that each backend on a passthrough route speaks TLS end to end on its own, and test the upstream with a real client handshake before routing production names to it. Review the stream proxy documentation for the exact upstream configuration this implies.

Security and operational considerations for passthrough routing

With passthrough, the certificate and private key stay on the backend. APISIX forwards the encrypted stream without terminating it, so the TLS certificate, its private key and the handshake all live on the service behind the gateway. Your team owns key generation, storage, permissions and rotation on those hosts or in their secret store, not in APISIX. Confirm where each backend's private key is kept, who can read it, and whether a compromise of the gateway would expose any key material. In most passthrough designs it should not, because the gateway never holds the key for those hosts. Also confirm that gateway mTLS is not part of the design, since it does not apply to passthrough routes, so client certificate checks must be done by the backend itself.

Certificate rotation happens outside the gateway. Because APISIX does not present a certificate for passthrough hosts, renewing a certificate means updating the backend and verifying the new chain, with no gateway change required for the handshake itself. Plan renewal windows with each backend owner and test expiry alerts against the real certificates served on the passthrough port. The SNI routing table is different: it lives in APISIX, and every host name you add or move changes which backend receives traffic. Keep stream routes in version control, require review for any change to a server_name or sni match, and use the Admin API role and access controls you set for the gateway so that routing edits follow the same change process as code. Wildcard SNI entries match as a suffix, so review them for unintended breadth before merging.

Logs will show the SNI name and connection metadata, but not the decrypted payload, because APISIX never decrypts it. This is useful for audit trails of which host was requested and when, and it limits what the gateway itself stores about user data. It also means payload-inspecting stream plugins cannot read traffic on passthrough ports, so any content-based controls must sit on the backend. Confirm with your security and privacy teams which fields your APISIX access and error logs record, where they are shipped and how long they are kept, and whether client IP addresses from the stream connection meet your retention rules.

Limits to confirm in your environment before you commit

Passthrough gives up visibility into the payload, so several behaviors that look routine in HTTP routing change. The cards below are the checks to run against your own hostnames, APISIX version and security requirements before you commit the design.

Wildcard SNI matching

Wildcard SNIs match as a suffix, so a route for *.payments.example.com will also catch any name that ends in that suffix. Check every hostname pattern you plan to publish against the routes, including apex domains and names that share a suffix with an internal zone. Test with real ClientHello traffic rather than only reading the route definitions.

Version and release notes

Stream proxy behavior and plugin support can change between releases, so confirm the exact APISIX version you will run and read its release notes for stream and TLS changes. The downloads page lists current releases and does not mark any as long-term support, so ask your vendor or team which upgrade cadence you will follow.

Load balancing and health checks

On a passthrough route the gateway cannot read HTTP responses, so health checks that depend on status codes or application content do not apply. Confirm which probe method works for your upstream, how a failed backend is removed from the pool, and how long-lived sessions behave when a node is drained. Test failover with open connections, not only new ones.

Clients that omit SNI

A client that sends no Server Name Indication gives the gateway no hostname to match, so the stream route may fall through to a default or fail. Decide whether such clients must be supported, identify any legacy tooling or IP-literal access in your estate, and test the rejection or default behavior before you publish the listener.

Gateway mTLS and upstream TLS

With passthrough enabled, gateway-side mTLS does not apply, and upstreams configured for the tls scheme return 503. Confirm whether your client certificate checks, audit rules or upstream trust model need to sit at the gateway or at the backend, and plan the certificate lifecycle on the service that terminates TLS.

WAF and identity requirements

Payload inspection, header-based authentication, WAF rules and plugins that read request content cannot run on a passthrough port. List every control your security policy and identity model require at the edge, and if any of them need the request in clear text, use termination on a separate port or move that control to the backend.

Questions buyers ask about TLS passthrough in APISIX

Is TLS passthrough the same as TLS termination in APISIX?

No. With passthrough, APISIX forwards the encrypted stream without decrypting it, so the gateway reads only the server name in the TLS ClientHello and routes on that. With termination, APISIX holds the certificate, decrypts the traffic, and can apply HTTP-level controls such as headers, authentication plugins and request-based rate limits. The choice changes what the gateway can see, what it can enforce, and who holds the certificate private key. Passthrough keeps the backend in control of TLS, while termination moves that responsibility to the gateway.

How much effort does a passthrough setup take, and what drives it?

The effort depends on the number of hostnames, the number of backends, and how many teams own them. A small setup with a few SNI routes on one stream listener is a contained task. Effort grows with the following factors:

  • The count of distinct SNI names and wildcard patterns that must map to separate upstreams.
  • Whether some backends still expect a scheme of tls, since those upstreams return 503 in passthrough mode and need to be changed or moved.
  • Whether the port must also carry termination routes, which requires a listener that supports both modes.
  • Testing across every client path, including health checks and failover between backend nodes.

Ask the partner to size these factors in the written scope rather than accept a single figure.

Can our own team set up passthrough using the documentation?

A team with working knowledge of APISIX stream mode, Linux networking and TLS can usually build a basic passthrough route from the stream proxy documentation. The harder parts are operational: deciding which features you give up, planning certificate ownership on each backend, wiring DNS to the right listener, and proving the behavior under failure. Teams that lack stream-mode experience often find the documentation sufficient for a lab but not for a production design. Consider whether your own engineers have time for a design review and a failure test before you commit.

What do we need to provide during a passthrough engagement?

Plan to supply three groups of input before work starts:

  • Certificates and keys for each backend, along with renewal ownership, because the gateway will not hold them.
  • DNS records for each hostname, and confirmation that each name resolves to the APISIX listener.
  • Named owners for each backend service who can confirm its TLS version, certificate chain, and expected client behavior.

Without these inputs, the design cannot be verified end to end, and the schedule is usually the first thing to slip.

Can mutual TLS still be enforced at the gateway with passthrough?

Not on a passthrough route. Gateway-level mTLS depends on APISIX terminating the client's TLS session and checking the client certificate, which passthrough does not do. If you need the gateway to verify client certificates, use a termination route for that hostname, or push client certificate verification to the backend that terminates TLS. Confirm this design with your security team, because moving verification to the backend changes where the policy is logged and who maintains it.

What should we ask for in a fixed-scope quote?

Ask the partner to state the scope in writing so the quote can be compared with other options. Useful items to request include:

  • The exact list of hostnames, wildcard patterns, and backends in scope.
  • Which routes use passthrough and which use termination, and the reason for each.
  • The features that will not be available on passthrough routes, and any compensating controls.
  • Test cases for SNI matching, backend failure, and certificate expiry.
  • Deliverables such as configuration as code, runbooks, and handover sessions.
  • Assumptions about your environment, and the input you must provide and by when.

A quote that covers these points lets you see what drives the price instead of comparing totals alone.

Which passthrough limitations should engineers check before they design routes?

Engineers should confirm that payload-inspecting plugins cannot run on passthrough ports, because the gateway never sees the decrypted data. Gateway mTLS does not apply, and scheme tls upstreams fail with a 503. Wildcard SNI entries match as a suffix, so overlapping patterns must be tested carefully. Review the stream proxy documentation against the APISIX version you plan to run, and confirm each behavior in a staging environment before you rely on it.

Where to read the stream proxy documentation

The primary reference for stream routes and TLS passthrough is the TCP/UDP dynamic proxying documentation. Read it before writing your first stream route, because it defines the settings this topic depends on: the tls_passthrough option on a stream listener, how stream routes are matched by SNI, and the limits that apply once the gateway stops reading the payload. Treat the examples there as the starting point for your own configuration, and confirm the exact field names against the version you plan to deploy, since the configuration schema can change between releases.

For the data plane context, read the deployment modes documentation next. It explains the three modes APISIX supports: traditional, decoupled and standalone. Traditional mode listens on port 9080 for client traffic and port 9180 for the Admin API, and the stream listener settings sit alongside those. Decide early which mode fits your environment, because it determines where stream routes are stored and how changes reach the data plane. If you plan to use file-driven standalone mode, the documentation describes how APISIX checks its configuration file every second and reloads it without a restart. Confirm with your own team how that reload interacts with long-lived encrypted sessions before you rely on it in production.

How DeployOpen scopes and delivers SNI routing for your APISIX gateway

DeployOpen plans TLS passthrough and SNI routing in APISIX as a written, fixed-scope piece of work inside infrastructure you control. The engagement starts with the hostnames, backends and encryption rules you need, then builds, tests and documents the stream routes that carry them.

How we scope

  • List every hostname, SNI pattern and backend that must stay encrypted end to end, including wildcard names.
  • Identify which routes need gateway-side mTLS, authentication or inspection, since passthrough cannot provide them.
  • Record which listener ports will mix passthrough and termination, and which stream plugins are excluded from those ports.
  • Agree deliverables, timelines and responsibilities in writing before any build work begins.

How we build

  • Configure the stream listeners and SNI routes in your chosen deployment mode, whether traditional, decoupled or standalone.
  • Test that backends with TLS-only upstreams are reachable and that unmatched SNI names fail predictably.
  • Check certificate handling on each backend, since the gateway never holds the private key for passthrough routes.
  • Confirm the routing table with a staged rollout on non-production traffic before any production cutover.

How we hand over

  • Deliver a route inventory showing each SNI pattern, its mode (passthrough or termination) and its owning backend.
  • Document the features given up on passthrough routes, so application teams know what to implement at the backend.
  • Provide runbooks for adding hostnames, rotating backend certificates and rolling back a route change.
  • Hand over configuration as code so changes can be reviewed and reproduced in your own repositories.

How we support

  • Ongoing support, upgrades and continuous testing are available as a retainer after handover.
  • Retainers can cover APISIX version upgrades and re-testing of routing rules when new hostnames are added.
  • Ask any quote to state which items are one-time build work and which recur under a support agreement.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.