Overriding DNS resolution in cURL is useful when a hostname must stay unchanged while one request is sent to a different backend. That makes it practical for canary checks, reverse-proxy validation, blue or green cutovers, and incident triage without editing /etc/hosts or changing DNS for any other application on the workstation.

The --resolve option adds a host:port:address entry to curl's in-memory DNS cache for the current command. curl connects to the supplied IP address, but it still keeps the hostname from the URL for the HTTP Host header and, on HTTPS, for SNI and certificate checks.

The match is exact on both hostname and port, so a mapping for api.example.test:18080 does not apply to api.example.test:18081 or api.example.test:443. Repeated --resolve flags let one command cover redirects or companion hostnames, and every mapping disappears when the command exits. The example names and output below are masked while keeping the same request shape as a real backend check.

Steps to override DNS resolution with cURL:

  1. Send the request with one --resolve entry so the URL hostname stays unchanged while the connection goes to the chosen address.
    $ curl --silent --show-error --resolve api.example.test:18080:127.0.0.1 \
      http://api.example.test:18080/
    host=api.example.test:18080
    server_port=18080

    Replace the example hostname, port, and address with the real values for the backend you need to test.

  2. Repeat the request with –verbose when you need to confirm that curl used the injected DNS entry and kept the URL host in the request.
    $ curl --silent --show-error --verbose --resolve api.example.test:18080:127.0.0.1 \
      http://api.example.test:18080/ --output /dev/null
    * Added api.example.test:18080:127.0.0.1 to DNS cache
    * Hostname api.example.test was found in DNS cache
    *   Trying 127.0.0.1:18080...
    * Connected to api.example.test (127.0.0.1) port 18080
    > GET / HTTP/1.1
    > Host: api.example.test:18080
    > User-Agent: curl/8.x
    > Accept: */*
    >
    * Request completely sent off
    * HTTP 1.0, assume close after body
    < HTTP/1.0 200 OK
    < Content-Type: text/plain; charset=utf-8
    ##### snipped #####
    * Closing connection

    Success is when the Trying and Connected lines show the override address while the Host: line still shows the hostname from the URL.

  3. Capture the final network destination with remote_ip when scripts or runbooks need a decisive success check.
    $ curl --silent --show-error --resolve api.example.test:18080:127.0.0.1 \
      --write-out '\nremote_ip=%{remote_ip}\n' \
      http://api.example.test:18080/
    host=api.example.test:18080
    server_port=18080
    
    remote_ip=127.0.0.1

    Use remote_ip when the response body alone is not enough to prove that the request reached the intended address.

  4. Add a separate mapping for every other port that the same hostname uses.
    $ curl --silent --show-error --resolve api.example.test:18081:127.0.0.1 \
      http://api.example.test:18081/
    host=api.example.test:18081
    server_port=18081

    A mapping for api.example.test:18080 does not apply to api.example.test:18081 or api.example.test:443. On HTTPS, curl still uses the hostname from the URL for SNI and certificate verification, so the certificate must match that hostname.