Error message
SSL routines:ssl3_read_bytes:tlsv13 alert certificate required
Also printed as
- error:0A00045C:SSL routines::tlsv13 alert certificate required
- SSL alert number 116
OpenSSL prints "error:0A00045C:SSL routines:ssl3_read_bytes:tlsv13 alert certificate required:…:SSL alert number 116"; curl prints "curl: (56) OpenSSL SSL_read: OpenSSL/<version>: error:0A00045C:SSL routines::tlsv13 alert certificate required, errno 0". Over TLS 1.2, the same situation usually ends with handshake_failure (alert 40) instead.
OpenSSL (client side) — TLS 1.3 alert 116 (certificate_required) from a mutual-TLS server
What it means
The server requires mutual TLS and the client finished a TLS 1.3 handshake without presenting a certificate, so the server answered with alert 116 (certificate_required). In TLS 1.3 the client certificate is checked after the client already considers the handshake complete, which is why tools such as curl report this during the first read (curl exit code 56) rather than during connect.
Why it happens
No client certificate configured
commonThe client was not given a certificate and key (curl without --cert, a library without its client-certificate option, a new machine without the certificate installed).
The client had a certificate, but not from an accepted CA
occasionalClients that choose a certificate automatically (browsers, some libraries) only send one issued by a CA in the server's "acceptable CA names" list; if none matches, they send nothing.
A proxy terminates TLS before the mTLS server
occasionalA load balancer or proxy between client and server terminates the first TLS connection and opens its own, without a client certificate, to the backend that requires one.
How to fix it
- 1.
Present the client certificate
Pass the certificate and private key to the client (curl --cert/--key, s_client -cert/-key, the HTTP library's client-certificate option).
bash openssl s_client -connect mtls.example.com:443 -servername mtls.example.com \ -cert client.pem -key client.key -brief </dev/null curl --cert client.pem --key client.key https://mtls.example.com/ - 2.
Read the CAs the server accepts
openssl s_client lists the "Acceptable client certificate CA names" the server sends; your certificate must chain to one of them.
bash # Which CAs does the server accept client certificates from? openssl s_client -connect mtls.example.com:443 -servername mtls.example.com </dev/null 2>/dev/null \ | sed -n '/Acceptable client certificate CA names/,/^Requested/p' - 3.
Check the certificate itself
It must be within its validity period, issued by an accepted CA, and its extendedKeyUsage (if present) must include clientAuth.
bash # The client certificate must be valid, issued by an accepted CA, and allow clientAuth openssl x509 -in client.pem -noout -subject -issuer -dates -ext extendedKeyUsage
Related errors
SSL routines:tls_process_client_certificate:peer did not return a certificateOpenSSL (server side, mutual TLS)SSL routines:ssl3_read_bytes:ssl/tls alert handshake failureOpenSSL (client side)SSL_do_handshake() failed (SSL: error:0A000418:SSL routines::tlsv1 alert unknow…nginx error log / OpenSSL400 No required SSL certificate was sentnginx