The command is curl -k. If that is genuinely all you needed, you can stop here.
The reason the rest of this article exists is that -k does not fix a certificate problem — it switches off the check that noticed one. curl's own documentation is unusually direct about this, saying it "strongly recommend[s] this is avoided" and that you should "never skip verification in production". That emphasis is theirs, not ours.
We are Geonode and we sell proxies, and the honest note here is that this problem has almost nothing to do with our product. Certificate errors are between your machine, its trust store and the server. There is one exception — an intercepting proxy on a corporate network is among the most common causes of this error, and it has a section below — but you will not solve a certificate error by buying anything, from us or anyone.
What is worth your time is the diagnosis. Certificate errors have a small number of specific causes, and for most of them there is a fix that takes about as long as typing -k and leaves verification switched on. A missing intermediate certificate, an out-of-date CA bundle, a corporate root certificate that curl does not know about, an expired certificate, a hostname mismatch. Each has a distinct signature and a distinct answer.
The practical risk of reaching for -k reflexively is not abstract. It is that the flag gets copied into a script, the script goes into production, and a check that would have caught a genuine interception problem is no longer running — in a place where nobody remembers it was ever turned off.
Everything below about curl's behaviour comes from curl's own SSL certificate documentation and the curl book.
The Command Everyone Came For
Here it is, with the variants.
# Skip verification of the server's certificate
curl -k https://example.com
# Same thing, long form
curl --insecure https://example.com
# Skip verification for the proxy's certificate as well
curl -k --proxy-insecure -x https://proxy.example.com:8080 https://example.com
-k and --insecure are the same option. --proxy-insecure is separate and applies to an HTTPS proxy's own certificate rather than the destination's — these are two independent verifications and disabling one does not disable the other.
See the Error Before You Silence It
Before reaching for the flag, spend ten seconds finding out what actually failed:
curl -v https://example.com
The verbose output shows the TLS handshake and the specific reason verification failed. "Unable to get local issuer certificate" is a very different problem from "certificate has expired", which is different again from a hostname mismatch — and each points at a different fix.
A more thorough look at the certificate the server is actually presenting:
curl -vI https://example.com 2>&1 | grep -A 20 "Server certificate"
This prints the subject, issuer and validity dates. Frequently the answer is visible immediately: the certificate expired last Tuesday, or it was issued for a different hostname, or the issuer is an organisation you have never heard of — which usually means something is intercepting your traffic.
The Habit Worth Forming
Diagnose first, then decide. -k is a legitimate tool for a one-off test against a server you control. It becomes a problem when it is the reflex rather than the conclusion, because the flag is silent about what it suppressed.
What -k Actually Turns Off
More than most people assume, and this is the part worth internalising.
By default, per curl's documentation, curl performs certificate verification by "verifying the signature and making sure the certificate was crafted for the server name provided in the URL".
That sentence describes two separate checks, and -k disables both.
Check One: The Signature Chain
Does this certificate chain up to an authority your system trusts? This is what proves the certificate was issued by a recognised certificate authority rather than generated by anyone with five minutes and an OpenSSL installation.
Without it, any certificate is accepted. A self-signed certificate made by whoever is between you and the server passes as readily as one from a real authority.
Check Two: The Hostname
Does this certificate actually belong to the host you asked for? A valid, properly issued certificate for attacker.example is still not a certificate for bank.example, and the hostname check is what enforces that.
Without it, a genuine certificate for any domain is accepted for any connection.
What Remains
The connection is still encrypted. TLS still negotiates a cipher and the traffic is not in plaintext on the wire.
But encryption without authentication protects you from a passive observer and not from an active one. The curl book puts the consequence plainly: with verification lowered, "your communication may be subject to Man-In-The-Middle attacks". Anyone positioned to intercept the connection can present their own certificate, terminate your TLS, read and modify everything, and open a separate connection onward. You would see a padlock's worth of encryption and none of its meaning.
Why This Matters More in Scripts
Interactively, you know you typed -k and you know why. In a script, the flag persists long after the reason is forgotten. Credentials get sent through it. Data comes back through it and is trusted.
If you must use it in automation, leave a comment saying why and what would need to change to remove it. That single line is the difference between a considered decision and an invisible one.
Why You Are Seeing the Error
Five causes cover nearly all of it, each with its own signature in the verbose output.
1. Missing Intermediate Certificate
The most common cause, and it is a server misconfiguration rather than a problem on your end.
Certificates chain: the server's certificate is signed by an intermediate authority, which is signed by a root your system trusts. The server is supposed to send its own certificate plus the intermediates. If it sends only its own, your client cannot complete the chain.
Browsers often paper over this by fetching missing intermediates automatically or caching them from previous visits. curl does not. So the characteristic symptom is a site that works perfectly in a browser and fails in curl — and the server is genuinely misconfigured; the browser is being generous.
Fix: have whoever runs the server configure the full chain. If it is your server, this is a five-minute change and it fixes every non-browser client at once.
2. Out-of-Date CA Bundle
Your system's list of trusted authorities is stale, so a legitimately issued certificate is not recognised. Common on older systems, minimal container images and long-lived virtual machines.
Fix: update the system's CA certificates package.
3. Corporate TLS Inspection
Your organisation's network decrypts and re-encrypts traffic, presenting its own certificate. Its own section below.
4. Self-Signed Certificate
Development servers, internal tools, appliances. There is no authority to chain to, because the certificate signed itself.
Fix: point curl at that certificate explicitly with --cacert, rather than disabling verification globally.
5. Genuinely Expired or Wrong Certificate
Sometimes the check is right. The certificate has expired, or it was issued for a different hostname, or the site is genuinely misconfigured.
Fix: tell whoever runs it. Using -k here means deliberately ignoring accurate information.
Reading the Verbose Output
"Unable to get local issuer certificate" points at cause 1, 2 or 3. "Certificate has expired" is cause 5 and needs no interpretation. A hostname mismatch is also cause 5. An unfamiliar issuer name is cause 3, and worth investigating rather than working around.
The Fixes In Order of Preference
Best to worst. Work down and stop when one applies.
1. Fix the Server
If it is a missing intermediate and you control the server, configure the full chain. This fixes it for every client, permanently, and is the only fix that improves anyone else's experience too.
2. Update Your CA Bundle
# Debian / Ubuntu
sudo apt-get update && sudo apt-get install --reinstall ca-certificates
# RHEL / Fedora
sudo update-ca-trust
# Alpine
apk add --no-cache ca-certificates && update-ca-certificates
That last one solves a very large share of certificate errors inside containers, where minimal images frequently ship without a CA bundle at all.
3. Point curl at the Right Certificate
For a self-signed or internal certificate, supply it explicitly. Verification stays on — you have simply told curl what to trust for this connection.
# A specific CA certificate file
curl --cacert /path/to/ca.crt https://internal.example.com
# A directory of certificates
curl --capath /etc/ssl/certs https://internal.example.com
This is the correct answer for internal services and development environments, and it is barely more effort than -k. The difference is that it still fails if something unexpected intercepts the connection, which is the entire point of the check.
4. Set It in the Environment
For a whole session or container, curl's documentation notes that you can "specify your own CA cert file by setting the environment variable CURL_CA_BUNDLE to the path of your choice", and that "SSL_CERT_FILE and SSL_CERT_DIR are also supported".
export CURL_CA_BUNDLE=/path/to/corporate-ca-bundle.crt
curl https://example.com # verification on, using your bundle
The last two variables are respected by a wide range of other tools as well, which makes this a good way to fix a whole environment at once rather than tool by tool.
5. Add the Certificate to the System Store
For a corporate root certificate you will encounter constantly, install it once at the system level. Every tool on the machine then works normally.
# Debian / Ubuntu
sudo cp corporate-root.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
6. Only Then, -k
And if you do, scope it as narrowly as you can: one command, one host, with a comment recording why.
Corporate TLS Inspection
The cause people find most confusing, because nothing appears to be wrong.
What Is Happening
Many organisations run equipment that inspects encrypted traffic for security and compliance purposes. To read TLS traffic, it has to decrypt it — which means terminating your connection, examining the contents, and opening its own connection onward.
To make this work without every browser complaining, the organisation installs its own root certificate on managed machines. Browsers and system applications trust it, so everything looks normal. The inspection appliance is performing exactly the interception that certificate verification exists to detect, and it has been authorised to do so.
Why curl Complains Anyway
curl may not use the system trust store, depending on how it was built and which TLS library it uses. So the corporate root that your browser accepts without comment is unknown to curl, and curl correctly reports that it cannot verify the chain.
The tell is in the verbose output: the certificate's issuer is your own organisation, or a security vendor's name, rather than a public certificate authority.
The Correct Fix
Export the corporate root certificate — your IT team can supply it, or you can extract it from a browser — and add it using one of the methods above. CURL_CA_BUNDLE for a shell session, the system store for a machine you use daily.
This keeps verification working. You are trusting one additional authority that your organisation has deliberately installed, rather than trusting everything.
The Wrong Fix
-k everywhere, permanently. It works, and it means you would not notice a genuinely malicious interception, because you have disabled the only mechanism that would have told you. On a network already performing legitimate interception, distinguishing that from illegitimate interception is precisely the capability worth keeping.
A Note on Containers
Containers do not inherit the host's trust store. A container that works on your laptop and fails in a corporate environment usually needs the corporate root added to the image or mounted in — which is a build-time fix, not a reason to disable verification in the Dockerfile.
Proxies and TLS
Our territory, and mostly a matter of knowing which certificate is being complained about.
Two Separate Verifications
When you route curl through an HTTPS proxy, there are two TLS connections and two independent checks.
Your connection to the proxy. Controlled by --proxy-insecure, --proxy-cacert and related options.
The connection to the destination. Controlled by -k, --cacert and the ordinary options.
Confusing these is a common source of wasted time. If curl complains about a certificate while a proxy is configured, work out which of the two connections failed before changing anything — the verbose output distinguishes them.
An Ordinary HTTP Proxy Does Not Cause This
With a standard HTTP proxy and an HTTPS destination, curl issues a CONNECT request and the proxy opens a tunnel. The TLS handshake then happens end to end between you and the destination, and the proxy cannot see or alter the certificate. If you are getting certificate errors through such a proxy, the cause is one of the ordinary ones from earlier, not the proxy.
This is also why an ordinary proxy cannot read your HTTPS traffic. It moves encrypted bytes without being able to interpret them.
An Intercepting Proxy Does
If a proxy is configured to inspect HTTPS, it terminates TLS and presents its own certificate — the corporate inspection case above, wearing different clothes. The signature is the same: an unfamiliar issuer in the verbose output.
The Rule
Add the proxy's certificate authority rather than disabling verification. Same reasoning as before, and same effort.
One related point that matters more for our customers than certificates do: check whether your hostname lookups are going through the proxy or being resolved locally. With curl, socks5h:// sends the hostname to the proxy while socks5:// resolves it on your machine. It is not a certificate issue, but it is the other way a proxy setup commonly does something other than what its owner intended.
In Code Rather Than curl
The same decision appears in every language, usually with a worse default ergonomics story.
Python
import requests
# Verification on, using a specific CA bundle — preferred
r = requests.get("https://internal.example.com", verify="/path/to/ca.crt")
# Verification off — equivalent to curl -k
r = requests.get("https://internal.example.com", verify=False)
requests emits a warning when verification is disabled, and a great deal of code on the internet suppresses that warning rather than addressing it. Suppressing the warning is strictly worse than the original problem, because it removes the last remaining signal that anything is unusual.
requests also respects REQUESTS_CA_BUNDLE, and SSL_CERT_FILE is widely honoured across the Python ecosystem — so the environment-variable approach from earlier often fixes a whole toolchain at once.
Node.js
// Preferred: supply the CA for this request
const https = require('https');
const fs = require('fs');
const agent = new https.Agent({ ca: fs.readFileSync('/path/to/ca.crt') });
// Avoid: disables verification for the entire process
// NODE_TLS_REJECT_UNAUTHORIZED=0
That environment variable deserves a specific warning. It is process-wide, so it disables verification for every connection the process makes, including ones you did not write — dependencies, telemetry, package downloads. Node itself prints a warning when it is set. Use NODE_EXTRA_CA_CERTS to add a certificate instead; it solves the actual problem without the collateral scope.
The Pattern
Every ecosystem offers both a targeted option and a global switch. The targeted one takes a few more characters and keeps the check working for everything you did not explicitly exempt.
The global switch is the one that ends up in a repository, gets copied into three other services, and is discovered two years later by someone trying to work out why an outage was not detected.
When Ignoring It Is Actually Fine
Not a section of prohibitions — there are genuine cases, and pretending otherwise makes the advice easy to dismiss.
A local development server you started yourself. You know exactly what is at the other end because it is on your own machine. -k against localhost is not a meaningful risk. Supplying the certificate with --cacert is still tidier and takes seconds.
A one-off interactive test where you are debugging the certificate itself. Determining whether the rest of the request works while a certificate issue is being fixed elsewhere is a perfectly reasonable use.
An isolated network you control end to end, where no path exists for an interceptor to sit on. Rare in practice, and worth being honest with yourself about whether it is really true.
Automated tests against ephemeral test infrastructure with self-signed certificates that are regenerated constantly. Even here, pointing at the certificate is usually possible and better.
When It Is Not Fine
Anything in production. curl's own documentation says never, and it is right.
Anything sending credentials. Without verification you cannot know who is receiving them.
Anything whose response you act on. Without verification the response could have been written by anyone in the path.
Anything on a network you do not control — public wifi, a client's office, a shared environment.
As a permanent fix for a recurring error. A recurring error has a cause. The cause has a fix. -k is a way of not finding out.
The One-Line Test
Ask: if someone were intercepting this connection right now, would I want to know?
If yes, keep verification on and fix the underlying cause. If genuinely no — a throwaway request to a machine on your desk — then -k is fine and this article has been longer than you needed.
People Also Ask
How do I ignore SSL certificate errors in curl?
curl -k https://example.com, or the long form --insecure. For an HTTPS proxy's own certificate, --proxy-insecure is separate. curl's documentation strongly recommends avoiding this and never doing it in production.
What does curl -k actually do?
It disables two checks: whether the certificate chains to a trusted authority, and whether it was issued for the hostname you connected to. The connection remains encrypted but is no longer authenticated, which means it may be subject to interception you cannot detect.
Why does curl give a certificate error when my browser does not?
Usually because the server is not sending its intermediate certificates. Browsers often fetch or cache missing intermediates automatically; curl does not. The server is misconfigured and the browser is being forgiving. It can also be that your browser trusts a corporate root certificate that curl does not know about.
How do I fix "unable to get local issuer certificate"?
In order: have the server send its full certificate chain, update your system's CA certificates package, or point curl at the correct certificate with --cacert. In containers, this is very often just a missing ca-certificates package.
How do I make curl trust a self-signed certificate?
curl --cacert /path/to/cert.crt https://internal.example.com. Verification stays enabled and curl trusts that specific certificate for that connection, which is safer and barely more work than -k.
Can I set a CA bundle for all curl commands?
Yes. Set CURL_CA_BUNDLE to your bundle's path. curl also supports SSL_CERT_FILE and SSL_CERT_DIR, which many other tools honour as well, making them a good way to fix an entire environment at once.
Does curl -k still encrypt my traffic?
Yes, the connection is still encrypted. But encryption without authentication only protects against passive observation. An active interceptor can present any certificate, decrypt everything, and pass it along — which is exactly what verification exists to prevent.
Is it safe to use curl -k in a Docker container?
Usually it is unnecessary. Minimal base images frequently ship without a CA bundle, so installing ca-certificates fixes it properly. If the cause is a corporate root certificate, add it to the image or mount it in rather than disabling verification.
Wrapping Up
curl -k is one keystroke and it works. What it does is switch off the mechanism that told you something was wrong, and the thing that was wrong is still wrong.
Spend ten seconds on curl -v first. Certificate errors have a handful of causes and each announces itself clearly. A missing intermediate certificate is the most common by far, and it explains the confusing case where a site works in a browser and fails in curl — browsers fetch the missing pieces, curl does not, and the server is genuinely misconfigured. In containers, the answer is very often just a missing ca-certificates package.
When you need to trust something unusual, trust it specifically. --cacert for one connection, CURL_CA_BUNDLE or SSL_CERT_FILE for an environment, the system store for a machine you use every day. Each of these keeps verification working while telling curl about the one additional authority you have decided to accept. They cost seconds more than -k and they still fail if something unexpected appears in the path, which is the whole reason the check exists.
On corporate networks, the cause is usually TLS inspection — and the fix is to add the organisation's root certificate rather than to stop checking. On a network already performing authorised interception, being able to distinguish that from unauthorised interception is worth more than usual, not less.
Proxies are largely a red herring here. An ordinary HTTP proxy tunnels HTTPS and cannot touch the certificate; if you are seeing errors through one, the cause is elsewhere. We sell proxies and there is nothing to sell you for this problem.
And if the answer to "would I want to know if someone were intercepting this right now" is no — a throwaway request to a server on your own desk — then -k is fine. It is the reflex, not the flag, that causes the damage.