496 SSL Certificate Required

When a request arrives without the required client certificate for mutual TLS, nginx responds with 496 SSL Certificate Required.

Usage

The 496 SSL Certificate Required status code indicates the client sent an HTTP request without an SSL certificate, yet the server requires one for the requested resource. Resolving this error requires resubmitting the request with a valid client certificate attached.

Example

A client sends a request to a resource requiring mutual TLS, but provides no client certificate. The nginx server records the failure as 496 SSL Certificate Required and, in the default configuration, answers the client with a 400 response carrying the built-in error page.

Request

GET /secure/internal HTTP/1.1
Host: www.example.re

Response

HTTP/1.1 400 Bad Request
Server: nginx
Content-Type: text/html
Connection: close

<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx</center>
</body>
</html>

The nginx error log records the missing certificate:

client sent no required SSL certificate

Requiring a client certificate

496 arises only under ssl_verify_client on. The optional mode verifies a certificate when one arrives and accepts a request without one, so a missing certificate never produces the code there.

ssl_client_certificate /etc/nginx/ssl/client-ca.crt;
ssl_verify_client on;

Switching between the two modes is the usual fix rather than a change on the client side. A public endpoint requiring certificates from a subset of clients wants optional together with an application level check on $ssl_client_verify, and an endpoint serving only certificate holders wants on.

if ($ssl_client_verify != SUCCESS) {
    return 403;
}

The handshake completes before the check runs, so the absence surfaces as an HTTP response rather than a connection failure, and the client sees 400 unless an error page changes the outcome.

error_page 496 =400 /errors/cert-missing.html;

location = /errors/cert-missing.html {
    root /var/www;
    internal;
}

Place the directive at server or http level. No location is selected at the point the condition arises, leaving a location block unmatched.

An error_page line anywhere in a server block replaces the whole inherited set from http level rather than adding to the set, so a lone error_page 404 in a server block silently removes an inherited certificate handler.

How to fix

The server expects a client certificate for mutual TLS (mTLS) and the client sent none. The fix depends on whether the client or server configuration needs to change.

Client-side fix

Install the required client certificate in the browser, operating system trust store, or HTTP client library. For curl, pass the certificate and key:

curl --cert client.pem --key client-key.pem \
  https://www.example.re/secure/internal

For browser access, import the .p12 or .pfx certificate bundle into the browser's certificate manager. The browser presents the certificate automatically during the TLS handshake when the server requests one.

Server-side fix

Check the ssl_verify_client directive. Three values control behavior:

# Reject if no cert (strict mTLS)
ssl_verify_client on;

# Accept with or without cert
ssl_verify_client optional;

# Accept without cert, skip CA verification
ssl_verify_client optional_no_ca;

Setting the value to optional allows requests without certificates to proceed while still verifying certificates when presented. This is useful for endpoints serving both authenticated and anonymous traffic.

Verify the ssl_client_certificate directive points to a valid CA bundle file containing all trusted root and intermediate certificates:

ssl_client_certificate /etc/nginx/ca-chain.pem;
ssl_verify_client on;

Use error_page 496 to serve a helpful error page or redirect to a login page instead of the default nginx error:

error_page 496 =301 https://$host/login;

See also

Last updated: August 17, 2026