Kong: an upstream host_header overrides what the target receives

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.

Code
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
Output
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.
Advertisement

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