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.
| Option | When it fits | Consequence to plan for |
|---|---|---|
| tls_passthrough route | Backends hold their own certificates and must see the client's TLS session end to end | Gateway mTLS does not apply and APISIX cannot read the payload |
| Scheme tls upstream | APISIX should terminate client TLS and open a TLS connection to the backend | Pointing a scheme tls upstream at a passthrough route returns 503 |
| Terminated TLS on the same listener | One port serves both passthrough and terminated services, and each stream route picks its mode | Stream plugins that inspect payloads only work on terminated routes |
| Exact SNI entry | A single known hostname maps to one backend and the routing table must stay tight | Each new hostname needs its own route entry or it will not match |
| Wildcard SNI entry | Many hosts under one domain share a backend pool, such as tenant subdomains | Matches as a suffix, so confirm the pattern does not catch hosts you did not intend |
| Payload-inspecting stream plugins | You need to read or transform traffic at layer 4 | Unavailable on passthrough ports, so move that control to the backend or to a terminated route |
| Gateway-level authentication and rate limits by request content | Policy depends on HTTP headers, paths or consumer identity | Not 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.
A terminated route ends TLS on the APISIX listener. The gateway holds the certificate and private key for the hostname, decrypts the stream, and then forwards the traffic onward. This is the mode to choose when the gateway must act on the connection itself, because it gives the platform team the same visibility and policy control they expect from other gateway routes. The trade-off is that the gateway becomes a place where plaintext exists and where key material must be protected.
- Certificate management: APISIX stores the certificate and key, so issuance, renewal and key storage become part of the gateway's operating model.
- Payload visibility: plugins can inspect and act on traffic that the route handles, subject to what your version supports for that protocol.
- Upstream encryption: if the backend requires TLS, configure the upstream connection deliberately and test it, since the terminated and upstream sides are separate connections.
- Client trust policy: client certificate requirements can be enforced at the gateway for that hostname.
- Exposure scope: a compromise of the gateway or its key store exposes the plaintext of every terminated route.
Before going live, list the certificates and keys each terminated hostname needs, who issues them, and where they are stored and backed up.
The decision is made hostname by hostname, and the useful question is what each service needs the gateway to do. Start from the backend: if the service owns its identity end to end, including its own certificate chain and client certificate validation, pass it through. If the gateway must read or enforce something on the payload, terminate it. Write the decision down with an owner, because a mixed estate is hard to audit when the reasons live only in someone's head.
- Inspection need: if a plugin or policy must read the payload, the route must terminate.
- Backend-owned identity: if the service requires end-to-end client certificate validation, passthrough keeps that check where the service runs.
- Compliance scope: ask your assessor whether gateway access to plaintext changes your audit boundary before you choose termination for regulated data.
- Decision register: keep a table of hostname, mode, owner, certificate source and reason, and review it when services change.
- Wildcard overlap: a wildcard SNI matches as a suffix, so a broad passthrough wildcard can capture hostnames you meant to terminate. Test specific and wildcard entries together.
For each hostname, confirm the chosen mode with a test before it reaches production, and revisit the register whenever a service changes its authentication model.
The mode is chosen per route, so the behavior you depend on must be confirmed in the APISIX version you run, not assumed from a design document. Read the stream proxy documentation for that release, then test each route against it. Verification should prove two things: that the right backend answers for each hostname, and that a terminated hostname cannot fall through to a passthrough route or the reverse. Repeat these checks after every upgrade, because stream behavior is what you will need to re-check first.
- Per-route confirmation: verify that both settings on one listener behave as documented in your release before relying on them.
- Handshake testing: use an OpenSSL client with the
-servernameoption to confirm which backend presents its certificate for each hostname. - Negative tests: send unknown and near-miss hostnames and confirm they are rejected or routed to the intended default.
- Certificate match: check that every passthrough backend certificate covers its hostname and that its expiry is monitored.
- Upgrade regression: rerun the SNI test set on a staging gateway before each APISIX upgrade.
Record the tested APISIX version beside the route design, so anyone reviewing the configuration knows exactly which behavior was verified.
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.
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.
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.
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.
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.
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.
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.

