Quick verdict: cURL's -k (or --insecure) skips SSL certificate verification entirely. Use it ONLY for local testing, self-signed certificates in dev environments, or one-off debugging. Never use it in production scripts — you lose the security guarantee that you are talking to the right server. The right fix for a "cert verification failed" error is almost always to use --cacert /path/to/ca-bundle.crt or to fix the cert chain.
The Flag
# Long form
curl --insecure https://localhost:8443
# Short form
curl -k https://localhost:8443Both are identical. With this flag:
- cURL does not check if the cert is signed by a trusted CA
- cURL does not check if the cert is expired
- cURL does not check if the cert hostname matches the URL
- The TLS connection still encrypts, but you cannot verify the server identity
When -k Is Acceptable
- Local dev with self-signed certs: running a Flask/Express app with a quick
openssl req -newkey ...generated cert. - Internal testing: staging environment behind a corporate CA that is not in your system trust store.
- One-off debug: proving a connection works before fixing the cert.
- Health checks against IP, not hostname: the cert is for
api.example.combut you are checking192.168.1.10.
When -k Is Dangerous
- Production scripts: you would not know if a man-in-the-middle intercepted your connection.
- CI/CD pipelines pulling secrets: a compromised network could feed false data.
- Anything touching customer data: compliance frameworks (PCI-DSS, HIPAA, SOC 2) explicitly forbid disabling cert validation.
- Scripts that ship to other machines: the disable flag travels with the script forever.
If your production script needs -k "just to make it work," you have a cert problem. Fix the cert.
The Right Alternatives
1. Self-signed cert: --cacert
Trust a specific cert without disabling all verification:
curl --cacert /path/to/server.crt https://localhost:8443cURL uses server.crt as the CA bundle for THIS request only. The rest of the system trust store is unchanged.
2. Corporate CA: --capath or system trust
Add the corporate root CA to your system trust store:
# Linux (Debian/Ubuntu)
sudo cp corp-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
# macOS
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain corp-root-ca.crt
# Windows (cURL ships with its own bundle)
curl --cacert C:path ocorp-ca.crt https://internal.corp.localAfter this, normal curl works without flags.
3. Hostname mismatch: --resolve
If your cert is for api.example.com but you want to test against IP 10.0.0.5:
curl --resolve api.example.com:443:10.0.0.5 https://api.example.com/healthcURL sends a SNI for api.example.com, validates the cert against that hostname, but actually connects to 10.0.0.5. Keeps verification on.
Common SSL Errors That Tempt -k
SSL certificate problem: unable to get local issuer certificate
Your system trust store does not have the CA that signed the server's cert. Fixes:
- Update
ca-certificatespackage:apt update && apt install --reinstall ca-certificates - If self-signed: use
--cacertas above - If corporate CA: import the CA into the system store
SSL: no alternative certificate subject name matches target host name
The cert is valid but for a different hostname. Solutions:
- Hit the actual hostname the cert is for
- Use
--resolve hostname:port:ipas above - Regenerate the cert with SAN entries for all hostnames you use
SSL certificate has expired
Renew the cert. -k would mask this and let your script keep "working" on an expired cert — bad. Set up Let's Encrypt + certbot for auto-renewal.
SSL Verification With Proxies
When using a proxy with HTTPS, cURL needs to verify two cert chains: the proxy itself, and the target through the proxy. Separate flags:
# Skip target cert check only
curl --proxy http://gw.spyderproxy.com:8000 -k https://target.com
# Skip proxy cert check only (rare, HTTPS proxies)
curl --proxy https://proxy.example.com:8000 --proxy-insecure https://target.com
# Trust specific cert for the target
curl --proxy http://gw.spyderproxy.com:8000 --cacert target.crt https://target.comFor SpyderProxy and most commercial residential proxies, the proxy uses standard CA-signed certs — no flags needed. The flags above are only for self-signed proxy setups.
Equivalents in Other Tools
| Tool | Disable SSL verification |
|---|---|
| cURL | -k or --insecure |
| Python requests | verify=False |
| Python urllib | context=ssl._create_unverified_context() |
| aiohttp | connector=aiohttp.TCPConnector(ssl=False) |
| httpx | verify=False |
| Node.js fetch | NODE_TLS_REJECT_UNAUTHORIZED=0 env var |
| wget | --no-check-certificate |
| git | git config --global http.sslVerify false (bad idea) |
All have the same warning: convenient for dev, dangerous for prod.
Auditing -k Usage
Find every script in a codebase that uses -k:
grep -rn "curl.*-k|curl.*--insecure" .Each match deserves a comment explaining why, or a refactor to remove. CI security scanners (Snyk, Semgrep) flag this pattern as a code smell.
Related: cURL basic authentication, curl vs wget, Fix SSL certificate errors.