When several targets sit behind one Upstream, each gets the upstream's name as its Host by default. host_header sets a fixed value instead - often required by virtual-hosted backends and TLS certificates.
curl -X PATCH http://localhost:8001/upstreams/billing-upstream \
--data host_header=billing.example.com
# With TLS to the upstream, the SNI follows this value, so a certificate
# issued for billing.example.com validates.
curl -X PATCH http://localhost:8001/services/billing \
--data url=https://billing-upstream \
--data tls_verify=true
Without host_header:
upstream sees Host: billing-upstream
TLS handshake SNI: billing-upstream -> certificate name mismatch
With host_header:
upstream sees Host: billing.example.com
TLS handshake SNI: billing.example.com -> valid
# preserve_host on the Route takes precedence over this: it sends the
# client's Host instead, and then the certificate has to match that.
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-08-25