Know what this test can and cannot prove
The curl project documents --resolve as a per-hostname and port entry in curl's name-resolution cache. For HTTPS, the URL hostname still drives SNI and certificate verification. That makes it useful when a new host is ready for your real domain but public DNS still points at the old host.
This tests a route from your machine to the specified destination. It does not prove public DNS propagation, browser rendering, background jobs, mail delivery, or behavior through a CDN you bypass. Some managed hosts require a documented preview hostname or authenticated origin access instead of direct IP access. Ask the host for its supported preflight method if the IP is shared, private, or protected.
Prepare a read-only page and a destination marker
Use a host you administer and an IP confirmed by that host. Have the new deployment expose an innocuous version marker in a public page or response header so you can distinguish it from the old deployment. Choose a read-only URL; avoid logout, unsubscribe, or action links whose GET request may change application state.
The examples below use example.com and 192.0.2.10 as placeholders, not a working destination. Replace both with your authorized hostname and new IP. Run from a local terminal where you understand proxy settings. An HTTP proxy can change the connection path, so inspect the observed remote IP and do not assume the override tested the origin if a proxy handled the request.
Fetch the page while keeping certificate checks enabled
Command template: curl --silent --show-error --connect-timeout 10 --max-time 30 --resolve example.com:443:192.0.2.10 --dump-header preflight-headers.txt --output preflight-body.html --write-out 'status=%{http_code} remote=%{remote_ip} effective=%{url_effective}' https://example.com/
Run in a new evidence directory: the two output filenames are overwritten if they already exist. Inspect the terminal result, headers, and body. Confirm the expected remote IP, expected status, and destination marker or known page text. curl can exit successfully even for an HTTP error response, so read the status explicitly. Do not add --insecure to make a certificate failure disappear; a production certificate failure is a failed check.
What happened when we ran it on this site
On 2 October 2026 we ran six cases against migration.editorialdeskmedia.com, a host we administer, using curl 8.7.1 on macOS. This is a demonstration on our own Cloudflare-served site, not a test of any hosting vendor. Public DNS returned 104.21.4.158 and 172.67.132.60.
The surprise was case 2. We pointed the hostname at an IP that DNS returns for a different, unrelated site on the same CDN. curl still got a 200 with a valid certificate, because that shared edge network answered for our hostname on an address DNS had given to someone else. A 200 there proves only that some edge served the name, not that you reached the new deployment. That is why the destination marker in the previous step matters.
Case 3 is the easiest mistake to miss: the override names port 80 while the URL is HTTPS on 443. curl silently ignored it and connected to the normal DNS address. Always compare remote_ip in the output with the address you meant to test.
- Print remote_ip with
--write-outon every run and compare it with the intended address. - Never add -k to a preflight; a certificate failure is the useful signal.
- On a CDN or shared edge, confirm a version marker or header unique to the new deployment.
| Case | Override | Result | What it shows |
|---|---|---|---|
| 1. Correct address | hostname:443 to 172.67.132.60 | 200, remote_ip 172.67.132.60, certificate verified | The override was used and the certificate matched the hostname |
| 2. Another site on the same CDN | hostname:443 to an IP of a different Cloudflare-served site | 200, certificate verified | On shared edges a 200 is not proof of destination; check a marker |
| 2b. Address on a different provider | hostname:443 to a GitHub IP | exit 60, certificate verification failed | Keeping certificate checks on catches a wrong provider |
| 2c. Same, with -k | hostname:443 to a GitHub IP, -k | 301 from the wrong server | -k hides the error and returns a misleading response |
| 3. Port mismatch | hostname:80 while the URL is https | 200 from 104.21.4.158 (normal DNS) | The override was silently ignored; compare remote_ip |
| 4. Old address that redirects | hostname:443 to 172.67.132.60, .html URL | 308 to the clean URL, not followed | Each redirect target is another destination to check |
Treat redirects as additional destinations
The first command deliberately does not follow redirects. If it returns a redirect, inspect the Location header and determine whether the target should also be on the new host. An apex-to-www redirect needs an override for www as well; overriding example.com:443 does not override every related hostname.
After checking the target, an HTTPS-only template is: curl --silent --show-error --location --max-redirs 5 --proto-redir '=https' --connect-timeout 10 --max-time 30 --resolve example.com:443:192.0.2.10 --resolve www.example.com:443:192.0.2.10 --output preflight-final.html --write-out 'status=%{http_code} remote=%{remote_ip} effective=%{url_effective}' https://example.com/
Use each hostname's actual destination IP; they need not be identical. An HTTP-to-HTTPS test requires a separate port-80 mapping. Record every intended hostname and port in the worksheet. Unexpected destinations, redirect loops, and HTTPS-to-HTTP downgrades require investigation before approval.
Build an acceptance matrix beyond the home page
| Check | Proposed passing evidence | Limit |
|---|---|---|
| Home and important inner pages | Expected status and new deployment marker | Does not execute browser JavaScript |
| Static assets and downloads | Expected file type and readable content | Does not prove every asset is present |
| Missing URL | Intentional 404 behavior | A 200 error page is a soft failure |
| Login and session | Browser test in supported staging route | curl page fetch is insufficient |
| Forms or checkout | Approved test transaction and receipt | Avoid real charges and external messages |
| Database and uploads | Reconciled counts and sampled records/files | Home page success says nothing about completeness |
| Jobs and integrations | Controlled run with observed result | Enabled configuration is not execution proof |
Define rollback around data, not just DNS
Hypothetical cutover rule: proceed only after the critical matrix rows pass, the final data sync is reconciled, and one owner has authority to stop the change. Keep the old host available for a defined rollback window. Record old DNS values, change time, and the point at which new writes begin.
If the new host accepts orders or uploads after cutover, restoring DNS alone can split or lose data. Decide in advance whether you will freeze writes, synchronize new records back, or use another application-specific recovery plan. Recheck the public domain after DNS changes without --resolve; a passing preflight only established the private test path. The worksheet separates preflight, public verification, and rollback readiness so none can be mistaken for the others.
Sources & verification
Product details and prices can change. Check the linked provider before buying.
- curl project: hostname resolution overrides and HTTPS Accessed 13 Sep 2026
- curl command manual: output, redirects, timeouts, and status Accessed 13 Sep 2026
Sources link directly to providers. Product buttons may use separately labeled affiliate links. Read our disclosure.