cURL Host Header: Set It With -H, --resolve or --connect-to
Quick fix
For plain HTTP, send the header yourself:curl -H 'Host: www.example.net' http://203.0.113.10/.
For HTTPS, pin the name to an IP instead so SNI, the certificate check and the Host header all use the real name:
curl --resolve www.example.net:443:203.0.113.10 https://www.example.net/.On this page
Setting the HTTP Host header with cURL is how you test a virtual host, a load balancer or a new server before you change DNS. This guide gives the exact commands for HTTP and HTTPS, explains why -H 'Host: ...' alone fails on HTTPS, and ends with a small hcurl shell helper so you never have to look the syntax up again.
When testing server configurations before DNS changes, you often need to connect to a server (e.g., server.example.com or an IP address) while requesting a different hostname (e.g., www.example.net). The web server, ingress controller or load balancer picks the site to serve from the HTTP Host header, so that is the value you need to control.
The cURL command for this looks like:
curl --header 'Host: www.example.net' http://server.example.com-H is the short form of --header, so this is the same request:
curl -H 'Host: www.example.net' http://203.0.113.10/Add -v to see the request curl sends and confirm the header went out:
curl -v -H 'Host: www.example.net' http://203.0.113.10/ 2>&1 | grep -i '^> host'
# > Host: www.example.netHTTPS: Use --resolve or --connect-to Instead
Overriding only the Host header works for plain HTTP, but on HTTPS it usually breaks. curl takes the TLS SNI name and the name it checks the certificate against from the URL, not from your -H header. If the URL is https://203.0.113.10/, the server receives no useful SNI, returns its default certificate, and curl fails with an error such as SSL: no alternative certificate subject name matches target host name.
The fix is to keep the real hostname in the URL and tell curl which IP address to connect to.
--resolve: pin a name to an IP
curl --resolve www.example.net:443:203.0.113.10 https://www.example.net/The format is HOST:PORT:ADDRESS. curl uses 203.0.113.10 for www.example.net on port 443 only, and everything else (SNI, certificate verification, the Host header) uses www.example.net. It is the curl equivalent of a temporary /etc/hosts entry. For an IPv6 address, wrap it in brackets: www.example.net:443:[2001:db8::10].
--connect-to: send the request to a different host and port
curl --connect-to www.example.net:443:origin.internal:8443 https://www.example.net/The format is HOST1:PORT1:HOST2:PORT2. curl still talks TLS and HTTP as www.example.net, but opens the TCP connection to origin.internal:8443. Use it when the target is a hostname rather than an IP, or listens on a different port.
Skipping certificate checks
If the server only has a self-signed or not yet issued certificate, add -k (--insecure) to skip verification while testing. Do not leave -k in scripts that run against production.
Lazy Solution 1: Bash Function
If you only need the HTTP form often, define a custom function, hcurl, which simplifies the syntax:
Bash Function Code
function hcurl() {
curl --header "Host: $1" "${@:2}"
}How It Works
$1grabs the first argument (the host for the header).${@:2}passes all other arguments tocurl.
This allows you to run:
hcurl www.example.net http://server.example.comYou can also add additional cURL options:
hcurl www.example.net --silent http://server.example.comExplanation of ${@:2}
$@: All arguments passed to the function.${@:2}: A Bash slice starting from the second argument.
This ensures hcurl passes everything after the first argument directly to curl.
Lazy Solution 2: TCSH Alias
For TCSH users, create an alias instead:
TCSH Alias Code
alias hcurl 'curl --header "Host: \!^" \!:2-$'How It Works
\!^: The first argument (equivalent to!:1).\!:2-$: All arguments from the second to the last.
You can now run:
hcurl www.example.net http://server.example.comExample with Additional Options
hcurl www.example.net --silent http://server.example.comFAQ
Why does curl ignore my Host header on HTTPS?
It does not ignore it: the header is sent inside the TLS session. The problem is that the TLS handshake happens first and uses the hostname from the URL for SNI and certificate checks. Use --resolve or --connect-to so the URL can keep the real name.
How do I test an Ingress or load balancer before DNS points to it?
Find the external IP of the load balancer and run curl -v --resolve app.example.com:443:<LB-IP> https://app.example.com/. If you get the default backend or a 404, the Host rule in the Ingress does not match; see Troubleshooting k8s Ingress.
Can I set the Host header and still follow redirects?
Yes, but be careful with -L. A custom Host: header set with -H is sent to every host curl follows, which can produce confusing results after a redirect to another domain. With --resolve, redirects to other names are resolved normally.
How do I remove the Host header entirely?
Pass the header name with nothing after the colon: curl -H 'Host:' http://203.0.113.10/. That is only useful for testing how a server handles HTTP/1.0 style requests.