Skip to content
ecdsa.com
Go crypto/tlsGo

Error message

remote error: tls: unknown certificate authority

Go servers log "http: TLS handshake error from <client>: remote error: tls: unknown certificate authority". In our tests, OpenSSL 3.5 clients rejecting the same certificate over TLS 1.3 were logged by the Go 1.27 server as "local error: tls: bad record MAC" instead, and Go clients send bad_certificate (logged as "remote error: tls: bad certificate").

Go crypto/tls — TLS alert 48 (unknown_ca) received from the peer, e.g. an OpenSSL-based client rejecting a Go server's certificate

What it means

The peer sent TLS alert 48 (unknown_ca): it could not chain the certificate it received to a CA it trusts. In a Go server's log it means a client (OpenSSL-based: curl, Python, Ruby, PHP, nginx as a proxy) rejected the server's certificate during a TLS 1.2 handshake. In a Go client it means the server rejected the client certificate in mutual TLS.

Why it happens

How to fix it

  1. 1.

    Check the served chain from a client

    If only the leaf is sent, fix the file; if the chain ends at a private root, install that root on the clients.

    bash
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:|Verify return code'
  2. 2.

    Serve the full chain from Go

    Put the leaf and its intermediates into the PEM file passed to ListenAndServeTLS (or tls.LoadX509KeyPair).

    go
    // Leaf + intermediates in one file; Go sends every certificate in it
    srv := &http.Server{Addr: ":443"}
    log.Fatal(srv.ListenAndServeTLS("fullchain.pem", "server.key"))
  3. 3.

    Install the private root on clients

    For internal services, distribute the company root to the systems and containers that call the server.

    bash
    # Private CA: install the root on the clients (Debian/Ubuntu example)
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt && sudo update-ca-certificates

Related errors

Browse the full signature error database