What it means: Go could not chain the server's certificate to any root in its trust pool.
certs.dInsecureSkipVerifyFree online tool — SSL certificate checker: instant results, no signup.
Runs a full TLS check: handshake, protocol versions, certificate chain, trust and expiry.
The text is the Error() string of Go's x509.UnknownAuthorityError: «x509: certificate signed by unknown authority» (crypto/x509/verify.go). Go built the chain from what the server sent and could not reach any root in the certificate pool it was given. Since Go 1.20, crypto/tls wraps verification failures in CertificateVerificationError, so the full line usually reads tls: failed to verify certificate: x509: certificate signed by unknown authority (Go 1.20 release notes).
Sometimes a hint follows: (possibly because of "..." while trying to verify candidate authority certificate "..."). Go found a certificate that looked like the right issuer, but checking its signature failed, for example because of an unsupported algorithm or a mismatched key. That hint points at the chain contents rather than at a missing root.
Because Docker, Kubernetes tooling, Terraform, Helm and many CLIs are written in Go, the same text appears in docker pull, kubectl and others. Other languages report the same situation as unable to get local issuer certificate (OpenSSL) or PKIX path building failed (Java).
| Cause | Where you see it | Fix |
|---|---|---|
| No CA certificates in the container | Binary in FROM scratch or a minimal image; every HTTPS call fails | Copy or install a CA bundle in the image |
| Private or self-signed CA on the server | Internal APIs, registries, Vault, test clusters | Add that root to the system store or the client's pool |
| TLS-inspecting proxy | Works at home, fails on the office network or CI | Trust the proxy's root explicitly |
| Server omits the intermediate | Browsers work, Go clients fail | Serve the full chain on the server |
| kubeconfig CA does not match the API server | kubectl after a cluster rebuild or certificate rotation | Refresh certificate-authority-data |
On Linux Go reads the first CA file it finds from a fixed list, including /etc/ssl/certs/ca-certificates.crt (Debian, Ubuntu), /etc/pki/tls/certs/ca-bundle.crt (Fedora, RHEL) and /etc/ssl/cert.pem (Alpine), plus certificate directories (crypto/x509/root_linux.go). A scratch image has none of them, so a statically linked Go binary that works on your laptop fails with this error in the container. The SSL_CERT_FILE and SSL_CERT_DIR environment variables override those locations (crypto/x509 SystemCertPool).
docker pull registry.example.com:5000/app fails with this error when the registry uses a private CA. The Docker daemon reads extra roots from a directory named after the registry: on a native Linux engine that is /etc/docker/certs.d/registry.example.com:5000/ca.crt, and every *.crt file there is added as a CA root (Docker documentation). Rootless Docker uses ~/.config/docker/certs.d instead, and Docker Desktop takes them from ~/.docker/certs.d on the host.
sudo mkdir -p /etc/docker/certs.d/registry.example.com:5000
sudo cp registry-root.pem /etc/docker/certs.d/registry.example.com:5000/ca.crt
docker pull registry.example.com:5000/appFor kubectl, the trusted CA is the certificate-authority-data field of the cluster entry in your kubeconfig. If the cluster was rebuilt or its CA rotated, fetch a fresh kubeconfig from the cluster's provisioning tool instead of adding insecure-skip-tls-verify.
openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null | grep -E '^ *[0-9] s:|^ *i:'A public CA means the client lacks roots or the server lacks an intermediate; a company or product name means a private CA or a proxy.scratch:FROM golang:1.23 AS build
# ... go build ...
FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /app /appOn Alpine or Debian bases, install the ca-certificates package.update-ca-certificates or update-ca-trust), or point the process at a bundle with SSL_CERT_FILE=/etc/ssl/private/bundle.pem.pool, _ := x509.SystemCertPool()
pool.AppendCertsFromPEM(rootPEM)
client := &http.Client{Transport: &http.Transport{
TLSClientConfig: &tls.Config{RootCAs: pool},
}}InsecureSkipVerify: true. It disables chain and host name checks for every connection that config makes.docker run --rm your-image # the request that failed should now succeed
openssl s_client -connect api.example.com:443 -servername api.example.com -CAfile /etc/ssl/certs/ca-certificates.crt </dev/null 2>/dev/null | grep 'Verify return code'
# Verify return code: 0 (ok)For a public endpoint, the SSL/TLS checker shows whether the chain your server sends reaches a publicly trusted root, which tells you whether to fix the server or the client.
SSL/TLS is the encryption protocol that protects data between the browser and server. Our tool analyzes the certificate, chain of trust, TLS version, and knownvulnerabilities.
Issuer, validity period, signature algorithm, covered domains (SAN), and validation type (DV/OV/EV).
Full chain verification: from leaf certificate through intermediates to root CA.
Protocol version (TLS 1.2/1.3), cipher suites, Perfect Forward Secrecy (PFS) support.
Set up a monitor — get Telegram and email alerts 30/14/7 days before expiration.
SSL certificate monitoring
TLS config audit
HTTPS as ranking factor
customer trust
www and subdomains.Strict-Transport-Security header forces browsers to always use HTTPS.SSL certificate monitoring, check history and alerts 30 days before expiry.
Sign up freeThe container has no CA bundle, which is typical for scratch and very small images. Copy /etc/ssl/certs/ca-certificates.crt into the image or install the ca-certificates package.
Put the registry's root certificate in /etc/docker/certs.d/registry-host:port/ca.crt on a native Linux engine. The daemon trusts every .crt file in that directory for that registry.
No. It turns off certificate and host name verification, so any machine in the path can impersonate the server. Add the right root to RootCAs instead.
Since Go 1.20 crypto/tls wraps verification errors in CertificateVerificationError, which adds that prefix. The cause is the x509 error after it.
On Linux, yes: SSL_CERT_FILE and SSL_CERT_DIR override where Go looks for system roots. Point SSL_CERT_FILE at a bundle that contains the missing root.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.