Error message
400 No required SSL certificate was sent
Also printed as
- client sent no required SSL certificate while reading client request headers
The page title is "400 No required SSL certificate was sent"; with a certificate that fails verification nginx shows "400 The SSL certificate error" instead. The log line is written at info level, so it is invisible with the default error_log level.
nginx — ssl_verify_client on, request without a client certificate
What it means
nginx is configured for mutual TLS (ssl_verify_client on) and the request arrived over a TLS connection on which the client presented no certificate. Instead of failing the handshake, nginx finishes it and answers every request with this HTTP 400 page, logging "client sent no required SSL certificate" at info level. The fix is on the client: it has to present a certificate issued by the CA in ssl_client_certificate.
Why it happens
The client did not send a certificate
commoncurl, scripts and API clients without --cert/--key or the equivalent library option; containers or CI jobs that lack the certificate secret.
The browser had no matching certificate
commonBrowsers only offer certificates issued by a CA that nginx advertises (taken from ssl_client_certificate); a certificate from another CA, or none imported, means the browser sends nothing.
A proxy terminates TLS before nginx
occasionalA CDN, load balancer or another nginx in front opens its own TLS connection without a client certificate; mutual TLS then has to be configured on that hop (or done at the edge).
How to fix it
- 1.
Present the client certificate
Pass certificate and key to the client; for browsers and Windows/macOS key stores, package them as PKCS#12 and import the file.
bash curl --cert client.pem --key client.key https://mtls.example.com/ # Browsers: import the client certificate with its key as PKCS#12 openssl pkcs12 -export -in client.pem -inkey client.key -out client.p12 - 2.
Proxying to an mTLS service: configure the upstream certificate
When nginx itself is the client of the mTLS service, proxy_ssl_certificate and proxy_ssl_certificate_key provide the certificate on the upstream connection.
text # nginx proxying to an mTLS upstream: present the client certificate on the upstream connection location / { proxy_pass https://mtls.example.com; proxy_ssl_certificate /etc/nginx/tls/client.pem; proxy_ssl_certificate_key /etc/nginx/tls/client.key; proxy_ssl_server_name on; } - 3.
Require certificates only where needed
ssl_verify_client optional plus a check of $ssl_client_verify per location keeps health checks and public paths reachable without a certificate.
text # Require the certificate only where needed ssl_verify_client optional; location /api/ { if ($ssl_client_verify != SUCCESS) { return 403; } }