Enable PROXY protocol
PROXY protocol makes the Hetzner load balancer pass the real client IP to your pods. Without it, every request appears to originate from the load balancer, which breaks rate limiting, WAF rules, audit logs, and any NetworkPolicy that matches on source IP.
Set it on both sides: the load balancer adds the header, and the backend reads it. If only one side is enabled, every connection breaks.
Turn it on
Enable it at the load balancer
Add the annotation to the type: LoadBalancer Service:
metadata:
annotations:
load-balancer.hetzner.cloud/uses-proxyprotocol: "true"
Warning
Simply deleting the load-balancer.hetzner.cloud/uses-proxyprotocol annotation from your Service does not disable PROXY protocol on the Hetzner Load Balancer. To turn it off, explicitly set the annotation to "false" (uses-proxyprotocol: "false"). Removing the annotation without setting it to "false" leaves the load balancer sending PROXY headers, which causes connection failures if your backend has stopped parsing them.
Tell the backend to read it
The backend side depends on what receives the connection.
Set use-proxy-protocol in the controller ConfigMap:
controller:
config:
use-proxy-protocol: "true"
Enable proxyProtocol on the entryPoint the load balancer targets (web or websecure). Traefik only trusts PROXY headers from IPs you list, so set trustedIPs to cover the sources that reach the entryPoint.
An application that reads the connection directly must parse the PROXY protocol header itself, before it reads the request bytes. Use a PROXY protocol library for your language rather than parsing the header manually.
What else it turns on
What else it turns on
The CCM automatically sets ipMode: Proxy in the Service status when the PROXY protocol is enabled. This ensures in-cluster requests to the public load balancer IP route through the load balancer and receive the required header. See Handle hairpinning .
Important
Enable PROXY protocol before you rely on anything that reads the client address: rate limits, a WAF, or source-IP network policies. Until both sides are set, those controls see the load balancer's address and behave as if every request came from one client.
For the wider picture, including the externalTrafficPolicy: Local alternative and how to verify what the pod sees, read Preserve the client source IP .
Tune health checks for node replacement
Set load balancer health checks so a node being drained and replaced leaves the target pool before it drops traffic.
Preserve the client source IP
Stop your pods from seeing the load balancer address instead of the real client, using PROXY protocol or externalTrafficPolicy Local.