Skip to content
ecdsa.com
Go crypto/tlsGo

Error message

remote error: tls: bad certificate

Go servers log "http: TLS handshake error from <client>: remote error: tls: bad certificate". OpenSSL-based clients send different alerts for the same rejection (unknown_ca with TLS 1.2), so the server-side text depends on the client's TLS library.

Go crypto/tls — TLS alert 42 received from the peer; typically logged by a Go server whose certificate a Go client rejected

What it means

The peer sent TLS alert 42 (bad_certificate). In a Go server's log ("http: TLS handshake error from …: remote error: tls: bad certificate") it means a client refused the server's certificate; Go clients send this alert for every verification failure (unknown authority, expiry, wrong name). In a Go client it means the server rejected the client certificate in mutual TLS. The real reason is only visible on the side that sent the alert.

Why it happens

How to fix it

  1. 1.

    Find the rejecting client and read its error

    The client address in the log tells you which service to look at; its error states the actual verification failure.

    bash
    # The log line names the client; its own error message says why it rejected the certificate
    journalctl -u myservice | grep 'remote error: tls: bad certificate' | grep -oE 'from [0-9a-f.:]+' | sort | uniq -c
  2. 2.

    Serve a complete, trusted chain

    Give the Go server a full-chain PEM file, issued by a CA all clients trust.

    go
    // Serve the full chain: leaf first, then intermediates, in one PEM file
    log.Fatal(http.ListenAndServeTLS(":443", "fullchain.pem", "server.key", nil))
  3. 3.

    Kubernetes: check the webhook's caBundle

    The caBundle must contain the CA that issued the webhook's serving certificate; cert-manager's CA injector keeps them in sync.

    bash
    # Kubernetes webhooks: the API server verifies the webhook's certificate with caBundle
    kubectl get validatingwebhookconfiguration my-webhook -o jsonpath='{.webhooks[0].clientConfig.caBundle}' \
      | base64 -d | openssl x509 -noout -subject -enddate

Related errors

Browse the full signature error database