How to Fix x509 Certificate Signed by Unknown Authority Error

The “x509: certificate signed by unknown authority” error means a client could not verify the TLS certificate presented by a remote server. Potential causes of this error include the certificate being self-signed, issued by an internal certificate authority (CA) the client does not trust, or the certificate chain being incomplete. This guide walks through every […]

Solving the “Certificate Signed by Unknown Authority” Problem
Key Points
  • Self-signed certificates and incomplete certificate chains often cause the "x509 certificate signed by unknown authority" error
  • Trusted CA-signed certificates are essential for secure, public-facing services, but can create errors if the CA isn't uploaded and trusted by both servers
  • SecureW2 Managed PKI is recommended for organizations lacking PKI infrastructure experience

The “x509: certificate signed by unknown authority” error means a client could not verify the TLS certificate presented by a remote server. Potential causes of this error include the certificate being self-signed, issued by an internal certificate authority (CA) the client does not trust, or the certificate chain being incomplete.

This guide walks through every common cause and fix for this X.509 certificate error across Docker, Kubernetes, Golang, Git, Terraform, and Helm so you can resolve it quickly and prevent it from recurring.

​​What Causes the ‘X509: Certificate Signed by Unknown Authority’ Error?

An X.509 certificate binds the identity of a server or client to a public key to prove the identity of a server (or client) during  a TLS handshake. When the signing CA is missing from the trust store of the machine or application making the connection, or the full CA chain cannot be verified, the handshake fails and you see this error.

The root causes of this X.509 error fall into a few categories:

Self-signed certificates: The certificate was not issued by a publicly trusted CA. Browsers, operating systems, and tools for interacting with services like Docker or Kubernetes all maintain trust stores that only include well-known public CAs by default. A self-signed cert is not in any of them.

Missing intermediate or root CA certificates: Even when a certificate was issued by a legitimate CA, the full chain must be present. If the intermediate CA certificate is missing from the server’s certificate bundle, clients cannot build a path back to a trusted root.

Internal or private CA not distributed: Many organizations operate an internal PKI with a private root CA. If that root CA has not been added to every system that needs to trust it, the error appears.

Corporate proxy or TLS inspection: Organizations that run TLS-intercepting proxies replace the original server certificate with one signed by the proxy’s own CA. Any client that lacks the proxy CA in its trust store will reject the connection.

 Expired certificates: A certificate past its validity period is treated as untrusted, producing the same error class.

Missing Subject Alternative Name (SAN): Go’s TLS library (and any tool built on it, including Terraform, Helm, and Kubernetes components) requires the hostname to be present in the certificate’s SAN field. A certificate with only a Common Name (CN) and no SAN will fail validation in these tools.

How to Verify the Certificate Chain

Before applying a fix, confirm exactly what is wrong. Use OpenSSL to inspect the certificate presented by the remote server:

“`bash openssl s_client -connect example.com:443 -showcerts “`

 Check the output for:

  • Issuer — is the issuing CA one your system should trust?
  • Validity dates — has the certificate expired?
  • SAN entries — does the certificate include the hostname you are connecting to?
  • Chain depth — are intermediate certificates present?

You can also inspect a local certificate file directly:

“`bash openssl x509 -in /path/to/cert.crt -text -noout “`

Look at the `Issuer`, `Subject`, `Not After`, and `X509v3 Subject Alternative Name` fields. This tells you whether the problem is an untrusted issuer, expiration, or a missing SAN.

Fix 1: Add the CA Certificate to the System Trust Store

If the certificate was issued by a private CA or internal PKI, add the root CA certificate to the operating system’s trust store. Here’s the specific commands to add root CA certificates in different operating systems:

Linux (Ubuntu / Debian)

“`bash sudo cp your-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates “`

Linux (RHEL / CentOS / Fedora)

“`bash sudo cp your-ca.crt /etc/pki/ca-trust/source/anchors/ sudo update-ca-trust “`

macOS

“`bash sudo security add-trusted-cert -d -r trustRoot \ -k /Library/Keychains/System.keychain your-ca.crt “`

Windows

“`powershell Import-Certificate -FilePath .\your-ca.crt ` -CertStoreLocation Cert:\LocalMachine\Root “`

After updating the trust store, restart the application or service that threw the error.

Fix 2: Use a Certificate From a Trusted Public CA Like Let’s Encrypt

For public-facing services such as websites, APIs, or SaaS endpoints the simplest fix is to replace the self-signed certificate with one from a trusted public CA. Let’s Encrypt is a common source for free, automated TLS certificates via the ACME protocol. 

To begin, install Certbot and request a certificate:

“`bash sudo certbot certonly –standalone -d yourdomain.com “`

Let’s Encrypt certificates are trusted by every major browser and operating system. They are valid for 90 days, and can be set to auto-renew, removing the risk of expiration-related errors. (Note, this is changing as of May 2026, when the certificate validity period will change to 45 days.)

For use cases where Let’s Encrypt does not apply — such as internal services, code signing, S/MIME email, or 802.1X network authentication — a managed PKI is the better path.

Fix 3: Resolve the Error in Docker

Docker containers built from minimal base images (scratch, Alpine, distroless) often lack a certificate bundle entirely. When the application inside the container makes a TLS connection, it has no trust store to validate against.

Alpine-Based Images

Add the `ca-certificates` package in your Dockerfile:

“`dockerfile RUN apk –no-cache add ca-certificates “`

Scratch or Distroless Images

Copy the certificate bundle from a builder stage:

“`dockerfile FROM golang:1.22 AS builder

Build steps:

FROM scratch COPY –from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY –from=builder /app /app ENTRYPOINT [“/app”] “`

Docker Private Registries

When pulling images from a private registry that uses an internal CA:

“`bash sudo mkdir -p /etc/docker/certs.d/registry.internal.com:5000/ sudo cp your-ca.crt /etc/docker/certs.d/registry.internal.com:5000/ca.crt sudo systemctl restart docker “`

Fix 4: Resolve the Error in Kubernetes

Kubernetes components (API server, kubelet, etcd) use TLS for all internal communication. The error surfaces when a node or pod does not trust the cluster’s CA.

Check the cluster CA:

“`bash kubectl config view –raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}’ | base64 -d | openssl x509 -text -noout “`

Add a CA to a node’s trust store, then restart kubelet:

“`bash sudo cp cluster-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates sudo systemctl restart kubelet “`

For Helm operations against a cluster with a custom CA, pass the CA bundle:

“`bash helm upgrade –install myrelease mychart \ –kube-ca-file /path/to/ca.crt “`

For Flux and GitOps controllers: If they connect to Git repos or Helm registries behind internal CAs, create a Kubernetes secret with the CA and reference it via `certSecretRef` in the `GitRepository` or `HelmRepository` resource.

Fix 5: Resolve the Error in Terraform and Go CLI Tools

Terraform, `kubectl`, Helm, and other Go-based tools use Go’s `crypto/x509` library, which enforces strict SAN validation. Two things to check:

SAN field: If your certificate only has a CN and no SAN, regenerate it with a SAN entry matching the hostname.

Trust store: Go reads the system trust store by default. Add your CA there (see Fix 1), or set the `SSL_CERT_FILE` environment variable:

“`bash export SSL_CERT_FILE=/path/to/ca-bundle.crt terraform plan “`

For Terraform Enterprise or Terraform Cloud agents behind a corporate proxy, configure the CA certificate in the agent’s environment. HashiCorp documents this in their support article on X.509 errors with Terraform CLI.

Fix 6: Resolve the Error in Git

Git can encounter an “x509: certificate signed by unknown authority” error when cloning or fetching over HTTPS from a server with an untrusted certificate. Here’s how to fix it:

Add the CA to Git’s certificate bundle:

“`bash git config –global http.sslCAInfo /path/to/your-ca.crt “`

For a specific repository only:

“`bash git config http.sslCAInfo /path/to/your-ca.crt “`

Avoid disabling TLS verification (`http.sslVerify false`) in production. It silences the error but removes all certificate validation, leaving connections vulnerable to interception.

How to Prevent X.509 Certificate Errors Long-Term

Fixing the immediate error is one thing. Preventing it across an organization requires a deliberate certificate management strategy.

Automate certificate issuance and renewal: Manual certificate processes lead to expiration, misconfiguration, and inconsistent trust stores. Automation eliminates these failure modes.

Distribute your CA to every endpoint: If you operate a private CA, build the root certificate into your golden images, container base images, and MDM configuration profiles. Every new machine or container should trust your CA from the start.

Monitor certificate expiration: Use tooling that alerts before certificates expire — not after users start hitting X.509 errors.

Use a managed PKI for internal certificates: Running your own CA with OpenSSL or Microsoft AD CS works on a small scale, but it becomes a maintenance burden as the organization grows. Certificate lifecycle management  gets increasingly complex with every new service, device, and environment.

Managed Solutions for X.509 Certificates

The “x509: certificate signed by unknown authority” error is a symptom of fragmented certificate management. A managed PKI from Secure W2 eliminates the root cause. Our solution automates certificate issuance, renewal, and revocation across every device and service in your environment. 

SecureW2 JoinNow Dynamic PKI is a cloud-native managed PKI that automates the full certificate lifecycle. It issues X.509 certificates to devices and users through ACME Device Attestation and Dynamic SCEP, integrates with identity providers (Entra ID, Okta, Google Workspace) and MDMs (Intune, Jamf, Kandji), and handles renewal and revocation automatically. Because it is fully managed, there is no on-prem CA infrastructure to maintain — no servers to patch, no CRLs to manage manually, no trust store distribution headaches.

For organizations that also use certificates for Wi-Fi and VPN authentication (802.1X with EAP-TLS), SecureW2 pairs Dynamic PKI with JoinNow Cloud RADIUS. This eliminates credential-based vulnerabilities from shared secrets, or PEAP-MSCHAPv2 by moving to phishing-resistant, certificate-based network access.

Talk to our team today to see how Dynamic PKI can replace manual certificate work for your team.


Frequently Asked Questions

What does "x509: certificate signed by unknown authority" mean?

This error means the TLS client could not find the signing CA in its trust store. The certificate might be self-signed, issued by an internal CA that has not been distributed, or missing intermediate certificates in the chain.

How do I fix the "x509: certificate signed by unknown authority" error in Docker?

Ensure your container image includes a CA certificate bundle. For Alpine images, install `ca-certificates`. For scratch images, copy `/etc/ssl/certs/ca-certificates.crt` from a builder stage. If connecting to a private registry, place the CA certificate in `/etc/docker/certs.d/<registry>/ca.crt`.

Why does this error appear in Kubernetes?

Kubernetes uses TLS between all components. If the cluster CA certificate is not in a node's trust store, or if a pod makes external TLS calls without the necessary CA bundle mounted, the error occurs. Add the CA to the node's trust store and restart kubelet, or mount the CA into the pod's filesystem.

Can I just disable TLS verification to fix it?

You can, but you should not in production. Disabling verification (`--insecure-skip-tls-verify`, `http.sslVerify false`, `InsecureSkipVerify: true`) removes all certificate validation. This makes connections vulnerable to man-in-the-middle attacks. Use it only for local development or debugging, and fix the root cause for production systems.

How do I prevent this error across my organization?

Automate certificate issuance and renewal, distribute your root CA to all endpoints and container images, monitor for expiration, and consider a solution like Managed PKI from SecureW2 to handle the full certificate lifecycle without maintaining on-prem CA infrastructure.