Check if a URL is reachable
Test whether a URL returns 2xx/3xx — useful for healthchecks, wait-for-it scripts, and CI smoke tests.
How to check if a url is reachable in each shell
Bashunix
curl -sSf --max-time 5 -o /dev/null https://example.com && echo OKZshunix
curl -sSf --max-time 5 -o /dev/null https://example.com && echo OKFishunix
curl -sSf --max-time 5 -o /dev/null https://example.com; and echo OKFish has no `&&` — use `; and` (and `; or` for `||`). Or write it as a multi-line `if test (curl …); echo OK; end`.
PowerShellwindows
try { Invoke-WebRequest -Method Head -Uri https://example.com -TimeoutSec 5 -UseBasicParsing | Out-Null; "OK" } catch { "FAIL: $_" }`Invoke-WebRequest` THROWS on non-2xx — wrap in `try/catch` to get a boolean-ish answer. `-UseBasicParsing` is mandatory on pwsh 5.1 in non-interactive sessions (the IE-engine fallback fails on Server Core where IE isn't installed); harmless and recommended on pwsh 7+.
cmd.exewindows
curl -sSf --max-time 5 -o NUL https://example.com && echo OKEquivalents listed for Bash, Zsh, Fish, PowerShell, cmd.exe.
Gotchas & notes
- `-f` (`--fail`) makes curl exit with non-zero on HTTP 4xx/5xx — without `-f`, curl returns 0 (success) even on a 500 response (it succeeded at *fetching*; the response just happens to be an error page). `-f` is the load-bearing flag for shell-script healthchecks.
- `--max-time SECS` caps the TOTAL request duration including DNS + connect + transfer. Different from `--connect-timeout SECS` which only caps the TCP connect step. For a strict 5s healthcheck, set both: `--connect-timeout 3 --max-time 5`. A slow-loris server can keep a connection open without sending bytes for hours otherwise.
- HEAD vs GET: `-I` (HEAD) is cheaper but some endpoints return 405 Method-Not-Allowed on HEAD (badly configured Rails / Django, some S3-compatible stores). When in doubt, GET with `-o /dev/null` and rely on `-f` for the exit code — bandwidth cost is small for healthcheck cadence.
- In a CI pipeline / Docker healthcheck: prefer `curl -fsS --retry 3 --retry-delay 2 URL` over a bare `curl URL`. The `--retry` handles transient flap on container boot. For `HEALTHCHECK CMD` in a Dockerfile, anchor with the explicit exit (`CMD curl -fsS --max-time 5 http://localhost:8080/health || exit 1`).
Related commands
Related tasks
- Send an HTTP POST request— POST a JSON body (or form fields, or a file) to a URL and capture the response.
- Get HTTP response headers— Inspect just the response headers of a URL — useful for debugging redirects, caching, CORS, and TLS.
- Follow HTTP redirects— Print the redirect chain (301/302/303/307/308 hops) from a starting URL to its final 2xx destination.
- Check SSL certificate expiry— Print the notBefore / notAfter dates of a remote site's TLS certificate (or a local .pem file).
- Test if a network port is open— Check whether a remote (or local) TCP port is accepting connections — for service health checks, firewall debugging, or pre-flight validation in scripts.