The command
curl https://httpbin.org/get
What the flags do
| Flag | What it does |
|---|---|
--cacert file | Trust the CA certificates in this PEM file instead of the system bundle. |
--cert file --key file | Present a client certificate (mutual TLS). |
--tlsv1.2 | Require at least TLS 1.2. --tls-max 1.2 sets an upper bound. |
-v | Print the handshake: protocol, cipher, certificate subject, issuer and dates. |
--resolve host:port:ip | Connect to a specific IP while still using the hostname for TLS. |
What verification checks
Curl checks two things. The certificate must chain to a certificate authority in its trust store, and the hostname in the URL must match a name on the certificate. If either fails, curl stops before sending the request and exits with an error, most often code 60. That is the feature working: the alternative is sending your request, and any credentials on it, to a server you could not identify.
-v shows what was presented. The lines to read are the subject, the subjectAltName match, the issuer and the expiry date.
curl -v -o /dev/null https://httpbin.org/get 2>&1 | grep -E "^\* +(SSL|subject|issuer|expire|subjectAltName|TLS)"
Private CAs and client certificates
Internal services often use certificates issued by a company CA that public trust stores do not know. The correct fix is to tell curl about that CA with --cacert; verification stays on. Mutual TLS adds a certificate of your own, which the server verifies in turn.
curl --cacert company-ca.pem https://internal.example.com/health
curl --cacert company-ca.pem \
--cert client.pem --key client-key.pem \
https://internal.example.com/orders
Testing a server before DNS points at it
To check a certificate on a new server, do not use the IP address in the URL; the hostname check would fail and you would also send the wrong Host. --resolve pins the name to an address for one command, so the request is exactly what real clients will send.
curl --resolve example.com:443:203.0.113.10 -I https://example.com/
Common mistakes
- Error 60 with a certificate that works in browsers usually means the server is not sending its intermediate certificate. Browsers fetch or cache it; curl does not.
- Error 35 is a handshake failure: no shared protocol version or cipher, or something on the port that is not speaking TLS.
- An outdated CA bundle on an old system breaks sites that are perfectly valid. Update the
ca-certificatespackage.
Related curl examples
Curl Ignore Certificate Checks Example
-k tells curl to proceed even though it cannot verify who it is talking to.
Curl SSL Request Example
Every https:// request curl makes is an SSL request in the everyday sense, although the protocol has been called TLS for a long time.
Curl Proxy Server Example
-x routes a request through a proxy.
Convert Curl to a Raw HTTP Request
Every curl command turns into a few lines of text sent over a socket.
HTTP vs HTTPS
What TLS protects, what stays visible, and the redirect that breaks API calls.
SSL Checker
See the certificate a server presents, its chain and its expiry date.
All Curl Examples
49 worked examples, grouped by what you are trying to do.
More under HTTPS and TLS
References
- curl man page: --cacert — Trusting a specific CA certificate file.
- curl: SSL certificate verification — How curl finds its CA store and what to do when verification fails.
These links leave api-tester.com, which is independent of the projects they point to.
FAQ
How do I make an HTTPS request with curl?
Use an https:// URL. Curl negotiates TLS and verifies the server certificate automatically, with no extra flags.
How do I fix "SSL certificate problem" in curl?
Find out why verification fails with -v. If the server uses a private CA, pass its certificate with --cacert. If the server omits an intermediate certificate, fix the server configuration.
How do I use a client certificate with curl?
Pass --cert with the certificate file and --key with the private key file. Add --cacert if the server certificate is issued by a private CA.