Mensaje de error
remote error: tls: unknown certificate authority
Los servidores Go registran «http: TLS handshake error from <client>: remote error: tls: unknown certificate authority». En nuestras pruebas, cuando clientes OpenSSL 3.5 rechazaban el mismo certificado con TLS 1.3, el servidor Go 1.27 lo registraba en cambio como «local error: tls: bad record MAC», y los clientes Go envían bad_certificate (registrado como «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
Qué significa
El otro extremo envió la alerta TLS 48 (unknown_ca): no pudo enlazar el certificado recibido con una CA de su confianza. En el registro de un servidor Go significa que un cliente (basado en OpenSSL: curl, Python, Ruby, PHP, nginx como proxy) rechazó el certificado del servidor durante un handshake TLS 1.2. En un cliente Go significa que el servidor rechazó el certificado de cliente en TLS mutuo.
Por qué ocurre
El cliente no confía en la CA emisora
frecuenteCA privadas o de la empresa que no tienen los equipos o contenedores cliente.
El servidor Go solo envía su certificado hoja
frecuenteListenAndServeTLS envía exactamente los certificados del archivo; con un archivo que solo contiene el certificado hoja, los clientes no pueden llegar a una raíz.
TLS mutuo: el servidor no confía en la CA del cliente
ocasionalEn el lado del cliente, esta alerta significa que el ClientCAs del servidor no incluye al emisor del certificado de cliente.
Cómo solucionarlo
- 1.
Comprobar desde un cliente la cadena servida
Si solo se envía el certificado hoja, corrige el archivo; si la cadena termina en una raíz privada, instala esa raíz en los clientes.
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.
Servir la cadena completa desde Go
Pon el certificado hoja y sus intermedios en el archivo PEM que se pasa a ListenAndServeTLS (o a 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.
Instalar la raíz privada en los clientes
Para los servicios internos, distribuye la raíz de la empresa a los sistemas y contenedores que llaman al servidor.
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