**TLS passthrough** establishes end-to-end encrypted connections directly between external clients and your backend pods, bypassing TLS termination at the ingress controller or load balancer. The Hetzner Load Balancer and internal cluster networking forward raw TCP byte streams without decrypting them, allowing your application to perform the TLS handshake and manage its own cryptographic keys. This architecture works natively because Hetzner Load Balancers operate at **Layer 4 (TCP)**. While Layer 7 (HTTP) load balancers must decrypt traffic to inspect URLs and headers, a Layer 4 proxy forwards raw packets untouched, delivering encrypted traffic directly to your application workloads. ## When to use TLS passthrough [Terminating TLS at the ingress controller](/docs/hetzner/apalla/network/expose/terminate-tls-at-ingress) is the standard approach for web traffic: the ingress controller handles certificate validation while applications communicate internally over HTTP. Use TLS passthrough instead when: - the application must see the client certificate for mutual TLS, - a compliance rule says the key never leaves the workload, - or the protocol is raw TCP or something other than HTTP, so an HTTP ingress cannot route it. ## Direct passthrough with a LoadBalancer Service For a standalone application, the simplest way to implement TLS passthrough is by exposing a standard `type: LoadBalancer` Service configured for TCP. The Hetzner Load Balancer forwards external connections directly to your application's secure port without intercepting the TLS stream: ```yaml title="service.yaml" apiVersion: v1 kind: Service metadata: name: my-app-tls annotations: load-balancer.hetzner.cloud/location: fsn1 spec: type: LoadBalancer selector: app: my-app ports: - name: https port: 443 targetPort: 8443 protocol: TCP ``` The application pod listens on port `8443`, loads its own TLS certificates, and negotiates the TLS handshake directly with the client. No intermediary component inspects or decrypts the connection. ## Multi-host routing with SNI To host multiple TLS applications behind a single load balancer without terminating certificates at the ingress, use **Server Name Indication (SNI)** to route connections: Enable [ssl-passthrough](https://kubernetes.github.io/ingress-nginx/user-guide/tls/#ssl-passthrough) `--enable-ssl-passthrough` on the controller, then annotate the Ingress resource with `nginx.ingress.kubernetes.io/ssl-passthrough: "true"`. The controller reads the hostname from the unencrypted TLS `ClientHello` packet and forwards the encrypted stream directly to your backend Service. For high-throughput or non-HTTP protocols, run an L4 proxy (like Envoy or HAProxy) configured for SNI inspection. The proxy routes TCP streams to target services based on the requested domain without terminating the TLS session. ## Keep the client address At Layer 4 the load balancer still replaces the source address. To provide the pod with the real client IP alongside the passed-through TLS, enable [PROXY protocol](/docs/hetzner/apalla/network/load-balancing/proxy-protocol) and have the application read the PROXY header before the TLS bytes. For the full picture of what the pod sees and the trade-offs, read [Preserve the client source IP](/docs/hetzner/apalla/network/load-balancing/preserve-client-source-ip). ## Trade-offs of TLS passthrough TLS passthrough delegates certificate management, renewal, and TLS configuration to each individual application pod. It also disables Layer 7 ingress capabilities like path-based routing, header transformations, and centralized certificate handling. [Terminating TLS at the ingress controller](/docs/hetzner/apalla/network/expose/terminate-tls-at-ingress) is recommended for standard web applications unless your workloads strictly require pod-level key custody, client mTLS validation, or non-HTTP protocols.