Mensaje de error
remote error: tls: bad certificate
Los servidores Go registran «http: TLS handshake error from <client>: remote error: tls: bad certificate». Los clientes basados en OpenSSL envían alertas distintas para el mismo rechazo (unknown_ca con TLS 1.2), así que el texto del lado del servidor depende de la biblioteca TLS del cliente.
Go crypto/tls — TLS alert 42 received from the peer; typically logged by a Go server whose certificate a Go client rejected
Qué significa
El otro extremo envió la alerta TLS 42 (bad_certificate). En el registro de un servidor Go («http: TLS handshake error from …: remote error: tls: bad certificate») significa que un cliente rechazó el certificado del servidor; los clientes Go envían esta alerta ante cualquier fallo de verificación (autoridad desconocida, caducidad, nombre incorrecto). En un cliente Go significa que el servidor rechazó el certificado de cliente en TLS mutuo. El motivo real solo es visible en el lado que envió la alerta.
Por qué ocurre
Un cliente Go no confía en el certificado del servidor
frecuenteCertificados autofirmados o de una CA privada, intermedios que faltan, certificados caducados o un nombre incorrecto; el propio registro del cliente muestra «x509: …».
TLS mutuo: el servidor rechazó el certificado de cliente
frecuenteSe ve en el lado del cliente cuando su certificado está caducado, lo emitió una CA que no es de confianza o le falta el uso clientAuth.
Webhooks de admisión y operadores de Kubernetes
ocasionalEl servidor de API (un cliente Go) rechaza el certificado de un webhook cuando el caBundle no coincide, y el servidor del webhook lo registra como bad certificate.
Cómo solucionarlo
- 1.
Encontrar el cliente que rechaza y leer su error
La dirección del cliente en el registro indica qué servicio revisar; su error indica el fallo de verificación real.
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.
Servir una cadena completa y de confianza
Dale al servidor Go un archivo PEM con la cadena completa, emitida por una CA en la que confíen todos los clientes.
go // Serve the full chain: leaf first, then intermediates, in one PEM file log.Fatal(http.ListenAndServeTLS(":443", "fullchain.pem", "server.key", nil)) - 3.
Kubernetes: comprobar el caBundle del webhook
El caBundle debe contener la CA que emitió el certificado de servicio del webhook; el inyector de CA de cert-manager los mantiene sincronizados.
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