NEWScrapingAnt MCP for Claude Code, Cursor & Windsurf — try it free →
Skip to main content

How to Ignore SSL Certificate Errors With Wget (and Trust One Instead)

· 15 min read
Oleg Kulyk
Co-Founder @ ScrapingAnt

How to Ignore SSL Certificate Errors With Wget (and Trust One Instead)

Updated 2026-09-16

Rewritten as a tested reference. Every command below was run by the example package against three local HTTPS servers (a self-signed certificate, an expired one, and one issued by a local internal CA) and the output is copied from that run: wget 1.25.0 built with OpenSSL on macOS, plus the same core cases on Debian's GnuTLS build of wget 1.21.3 in a container. The 2024 version presented SSL_CERT_FILE as a wget feature; measured, it works on the OpenSSL build and is ignored on the GnuTLS build. New: the error messages and their causes on both builds, .wgetrc, --ca-directory, --pinnedpubkey, the internal-CA case, exit codes. Gone: a stray "Meta Description" section, unsourced breach statistics, and a wrapper script.

The flag you are looking for, run against the package's self-signed test server (substitute your URL):

wget -nv -O- --no-check-certificate https://localhost:8443/index.html
WARNING: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

The download proceeds and the warning stays. The one-line way to make the error go away without switching verification off, when you have the server's certificate or your CA file:

wget -nv -O- --ca-certificate=certs/localhost.pem https://localhost:8443/index.html
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

The rest of this page shows what each option does with the real output, how to read the different error messages, how to make a setting permanent, and what does and does not work depending on how your wget was built. Prefer curl? See How to ignore SSL certificate errors in cURL; the same problem in Python is in Python Requests: ignore SSL certificate errors.

The setup, and how the outputs were captured

The package generates three certificates with a small Python script: certs/localhost.pem (self-signed for the name localhost), certs/expired.pem (valid from 2024-01-01 to 2024-02-01), and certs/internal.pem, a leaf issued by a generated Example Internal CA (certs/ca.pem). It serves https://localhost:8443, :8444 and :8445 with them. Commands run with -nv -O- (one line per event, page body to stdout; -O /dev/null for the two public-site fetches) and under LC_ALL=C, so messages are in English with plain quotes; exit= is wget's exit status; wget's timestamp is masked as <time>. The main run is on this build:

GNU Wget 1.25.0 built on darwin24.1.0.
+ssl/openssl
wget links: /opt/homebrew/opt/openssl@3/lib/libssl.3.dylib
that OpenSSL: OpenSSL 3.6.3 9 Jun 2026 (Library: OpenSSL 3.6.3 9 Jun 2026)

That +ssl/openssl line matters for sections 3 and 6. wget --version prints +ssl/openssl or +ssl/gnutls, and the package also ran the core cases on Debian 12's wget 1.21.3, a +ssl/gnutls build, inside a container (those commands carry -4, because the container's test server listens on IPv4 only, and keep the certificates under /tmp/certs); where the two builds differ, both outputs are shown.

1. What the failure looks like

wget -nv -O- https://localhost:8443/index.html
ERROR: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
To connect to localhost insecurely, use `--no-check-certificate'.
exit=5

Nothing is downloaded and the exit status is 5, "SSL verification failure" in the manual's exit-status list, so a script can tell this apart from a network error (4) or an HTTP error (8). The GnuTLS build words the same failure differently:

wget -4 -nv -O- https://localhost:8443/index.html
ERROR: The certificate of 'localhost' is not trusted.
ERROR: The certificate of 'localhost' doesn't have a known issuer.
exit=5

2. --no-check-certificate

The first-screen command above. The manual's description is exact: wget does not check the certificate against the available authorities and does not require the URL host name to match the name in the certificate. The warning is still printed, so a log will show every insecure fetch (on the GnuTLS build it is two lines: WARNING: The certificate of 'localhost' is not trusted. and WARNING: The certificate of 'localhost' doesn't have a known issuer.). Both checks are off at once, which is the reason to prefer section 3 for anything you will run more than once: with --no-check-certificate, anyone between you and the server can present any certificate and you will download what they serve.

3. Trust the certificate instead

If the server is yours, give wget its certificate and keep verification on (the first-screen example). If your organisation runs an internal CA, the failure names the issuer and says the authority cannot be verified locally:

wget -nv -O- https://localhost:8445/index.html # leaf signed by an internal CA
ERROR: cannot verify localhost's certificate, issued by 'CN=Example Internal CA':
Unable to locally verify the issuer's authority.
To connect to localhost insecurely, use `--no-check-certificate'.
exit=5

The fix is the CA's certificate, not the server's:

wget -nv -O- --ca-certificate=certs/ca.pem https://localhost:8445/index.html
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8445/index.html [74/74] -> "-" [1]
exit=0

--ca-certificate adds to the system store rather than replacing it. A file containing only the test certificate still lets wget verify a public site:

wget -nv -O /dev/null --ca-certificate=certs/localhost.pem https://scrapingant.github.io/scrapingant-examples/fixtures/dynamic-delayed.html # public site, only our CA file given
<time> URL:https://scrapingant.github.io/scrapingant-examples/fixtures/dynamic-delayed.html [752/752] -> "/dev/null" [1]
exit=0

The same holds on the GnuTLS build (the container run repeats this fetch with exit 0). That is the opposite of how Python's requests treats verify=<path>, where the path replaces the bundle; if you come from there, no concatenation is needed here. For a directory of CA files, wget wants the hashed layout OpenSSL's c_rehash produces; openssl rehash is the same tool:

openssl rehash cadir; ls cadir; wget -nv -O- --ca-directory=cadir https://localhost:8443/index.html
ce275665.0
localhost.pem
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

The manual notes that a directory is more efficient than a bundle when many certificates are installed, because wget loads them on demand. One difference between the builds: on the OpenSSL build a directory is additive like the file (the public-site fetch with only --ca-directory=cadir succeeds), on the GnuTLS build it is not:

wget -4 -nv -O /dev/null --ca-directory=/tmp/cadir https://scrapingant.github.io/scrapingant-examples/fixtures/dynamic-delayed.html
ERROR: The certificate of 'scrapingant.github.io' is not trusted.
ERROR: The certificate of 'scrapingant.github.io' doesn't have a known issuer.
exit=5

So on Debian, --ca-directory replaces the system store; use --ca-certificate when the same command must reach public sites too.

4. Reading the error messages

Which fix applies depends on which message you got. All of them are exit 5.

Self-signed (section 1) or untrusted issuer (section 3): trust the certificate or the CA with --ca-certificate, or use --no-check-certificate for a one-off.

Hostname mismatch: the certificate is fine and the name you used is not in it. Same server, addressed by IP:

wget -nv -O- --ca-certificate=certs/localhost.pem https://127.0.0.1:8443/index.html
ERROR: certificate common name 'localhost' doesn't match requested host name '127.0.0.1'.
To connect to 127.0.0.1 insecurely, use `--no-check-certificate'.
exit=5

Fix: use the name the certificate was issued for, or reissue it with the right subject alternative names. --no-check-certificate also "fixes" this by skipping the check that just told you something useful.

Expired: the second server's certificate ended its validity on 2024-02-01, and trusting it does not help:

wget -nv -O- --ca-certificate=certs/expired.pem https://localhost:8444/index.html
ERROR: cannot verify localhost's certificate, issued by 'CN=localhost':
Issued certificate has expired.
To connect to localhost insecurely, use `--no-check-certificate'.
exit=5

Fix: renew the certificate on the server. If you cannot, --no-check-certificate downloads anyway, and because this certificate is also self-signed, the warning it prints is the self-signed one, not "expired":

wget -nv -O- --no-check-certificate https://localhost:8444/index.html
WARNING: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8444/index.html [74/74] -> "-" [1]
exit=0

For a known server you must keep fetching with an expired certificate, section 7's pin plus --no-check-certificate is the tighter option.

5. Making it permanent: .wgetrc and -e

Every option above has a .wgetrc form. check_certificate = off is --no-check-certificate; ca_certificate = file and ca_directory = directory are the trusted forms. The package writes a startup file and points wget at it with WGETRC (the default location is ~/.wgetrc):

printf 'check_certificate = off\n' > wgetrc.test; WGETRC=wgetrc.test wget -nv -O- https://localhost:8443/index.html
WARNING: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

-e sets any .wgetrc command for one run, which is convenient in scripts that must not depend on the user's startup file:

wget -nv -O- -e check_certificate=off https://localhost:8443/index.html
WARNING: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

A check_certificate = off line in ~/.wgetrc disables verification for every host, forever, silently except for the warning; put ca_certificate = /path/to/internal-ca.pem there instead if an internal CA is the reason.

6. SSL_CERT_FILE depends on how wget was built

The 2024 version of this page listed SSL_CERT_FILE and SSL_CERT_DIR as ways to point wget at a CA file. They are OpenSSL's environment variables, read when OpenSSL loads its default verify paths, and wget's manual does not mention them. On the OpenSSL build they work:

SSL_CERT_FILE=certs/localhost.pem wget -nv -O- https://localhost:8443/index.html # wget built with +ssl/openssl
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

On Debian 12's GnuTLS build, the same command is ignored and the fetch fails exactly as with no variable at all:

SSL_CERT_FILE=/tmp/certs/localhost.pem wget -4 -nv -O- https://localhost:8443/index.html
ERROR: The certificate of 'localhost' is not trusted.
ERROR: The certificate of 'localhost' doesn't have a known issuer.
exit=5

while --ca-certificate works on that build too. Ubuntu's package, despite being Debian-derived, is built against OpenSSL (it depends on libssl3, not GnuTLS); the variable was not measured there. Check yours with wget --version, and prefer --ca-certificate or the .wgetrc form, which work on both builds.

7. Pin the server's public key

--pinnedpubkey takes a public key file or one or more sha256// hashes and aborts the connection if the server's key does not match. The hash is computed from the certificate's public key:

PIN=$(openssl x509 -in certs/localhost.pem -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64); wget -nv -O- --no-check-certificate --pinnedpubkey="sha256//$PIN" https://localhost:8443/index.html
WARNING: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

With a wrong hash the connection is refused before any data moves:

wget -nv -O- --no-check-certificate --pinnedpubkey="sha256//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" https://localhost:8443/index.html
WARNING: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
The public key does not match pinned public key!
exit=5

Pinning is a check in addition to certificate verification, not a replacement for it. Without --no-check-certificate (or --ca-certificate), the self-signed certificate still fails verification first:

wget -nv -O- --pinnedpubkey="sha256//$PIN" https://localhost:8443/index.html # no --no-check-certificate
ERROR: cannot verify localhost's certificate, issued by 'CN=localhost':
Self-signed certificate encountered.
To connect to localhost insecurely, use `--no-check-certificate'.
exit=5

So the combination --no-check-certificate --pinnedpubkey=… is the honest way to talk to a self-signed server you know: the CA check is off, but only the one key you pinned is accepted, and the warning still records that the CA check was skipped.

8. Protocol version and HTTPS-only

--secure-protocol forces a TLS version when a server misbehaves with the automatic choice; the manual's values are auto (default), SSLv2, SSLv3, TLSv1, TLSv1_1, TLSv1_2, TLSv1_3 and PFS:

wget -nv -O- --secure-protocol=TLSv1_2 --ca-certificate=certs/localhost.pem https://localhost:8443/index.html
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<time> URL:https://localhost:8443/index.html [74/74] -> "-" [1]
exit=0

--https-only is a recursive-mode option (only HTTPS links are followed); it does not affect a single download.

9. When the store is stale, not the site

If public sites fail verification on an old machine while they work elsewhere, the CA store wget uses is probably out of date (a TLS-intercepting proxy or a wrong system clock gives the same symptom; section 3's --ca-certificate with the proxy's CA covers the first, and date the second). On Debian and Ubuntu, reinstall or update ca-certificates and run update-ca-certificates; on RHEL-family systems, update-ca-trust. These commands are documented here, not run by the package (they change the machine). The manual says that without --ca-certificate or --ca-directory, wget looks for CA certificates at the system-specified locations chosen at OpenSSL installation time.

10. The same thing in curl

curl -sS https://localhost:8443/index.html; echo; curl -sS -k https://localhost:8443/index.html; curl -sS --cacert certs/localhost.pem https://localhost:8443/index.html
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
<!doctype html><title>self-signed fixture</title><p>served over HTTPS</p>
exit=0

-k is curl's --no-check-certificate, --cacert its --ca-certificate (this is Apple's curl with LibreSSL; a curl on OpenSSL 3 spells the message "self-signed certificate"); the full curl story, including proxies, is in How to ignore SSL certificate errors in cURL.

Exit codes on this page

ExitMeaning (manual, "Exit Status")Seen above
0no problemsevery successful fetch
5SSL verification failureself-signed, untrusted issuer, hostname mismatch, expired, wrong pin

When ScrapingAnt is not needed, and when it is

None of the cases on this page needs a scraping service: they are your server, your CA, your proxy or your CA store. Where a public site refuses your requests for other reasons and you fetch it through the ScrapingAnt API instead, the certificate question moves: when you call the ScrapingAnt API, your code makes one TLS connection, to api.scrapingant.com; the target page is fetched by ScrapingAnt's infrastructure, so the target's certificate is not something your client verifies. See the request and response format.

Limitations

  • The main run is wget 1.25.0 built with OpenSSL (Homebrew, macOS, linking openssl@3 3.6.3); the GnuTLS run is Debian 12's wget 1.21.3 in a container and covers the default, --no-check-certificate, --ca-certificate (local and public site), --ca-directory (public site) and SSL_CERT_FILE cases only.
  • The system-store commands in section 9 are documented, not run.
  • Client certificates (--certificate, --private-key) and CRLs (--crl-file) are out of scope.

Examples tested on 2026-09-16 with GNU Wget 1.25.0 (+ssl/openssl, Homebrew openssl@3 3.6.3) and, in a Debian 12 container, GNU Wget 1.21.3 (+ssl/gnutls); curl 8.7.1. Code: scrapingant-examples/examples/wget-ignore-ssl.

Related: How to send POST requests with Wget, How to download images with Wget, How to use proxies with Wget, How to use Wget with cookies.

This article was drafted with AI assistance from a tested evidence packet and reviewed by the named author, who is responsible for the code, measurements and corrections.

Forget about getting blocked while scraping the Web

Try out ScrapingAnt Web Scraping API with thousands of proxy servers and an entire headless Chrome cluster