Error message
SSL routines:tls_process_client_certificate:peer did not return a certificate
Also printed as
- error:0A0000C7:SSL routines::peer did not return a certificate
OpenSSL 3.x logs "error:0A0000C7:SSL routines:tls_process_client_certificate:peer did not return a certificate:<source>". nginx does not use this path: with ssl_verify_client on it completes the handshake and returns HTTP 400 "No required SSL certificate was sent" instead.
OpenSSL (server side, mutual TLS) — SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE
What it means
This is the server-side record of a failed mutual-TLS handshake: the server required a client certificate (SSL_VERIFY_FAIL_IF_NO_PEER_CERT) and the client sent none. The server then aborts with an alert (certificate_required in TLS 1.3, handshake_failure in TLS 1.2), which the client sees as an alert error.
Why it happens
The client has no certificate configured
commonA new deployment, a rotated secret that did not reach the client, or a library that was not given its certificate and key.
Load balancer health checks and monitoring
commonHealth checkers usually connect without a client certificate; on a server that requires one for every connection, they produce a steady stream of these lines.
The client found no certificate matching the server's CA list
occasionalBrowsers and some libraries only offer a certificate issued by one of the CAs the server advertises; otherwise they send an empty certificate message.
How to fix it
- 1.
Configure the client certificate
Give the client its certificate and key and test with curl --cert/--key.
bash # Test from the client side with a certificate curl --cert client.pem --key client.key https://mtls.example.com/ - 2.
Make the certificate optional where it must be
Servers that also serve health checks or public paths can request certificates optionally and enforce them per location.
text # nginx: request but do not require a certificate on paths that must stay open (health checks) ssl_verify_client optional; location /internal/ { if ($ssl_client_verify != SUCCESS) { return 403; } } - 3.
Check the advertised CA names
The issuer of the client certificates must be in the list the server sends, or clients that select certificates automatically will not offer one.
bash # The CA list the server advertises must include the issuer of the client certificates 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'