nginx/nginx · error

-ERR No required SSL certificate

Error message

-ERR No required SSL certificate

What it means

POP3 flavor of the missing-client-certificate banner ('no_cert' field of ngx_mail_protocol_t, src/mail/ngx_mail_pop3_module.c:60). Set in ngx_mail_verify_cert (src/mail/ngx_mail_handler.c:424-443): when 'ssl_verify_client on' (mandatory mode, sslcf->verify == 1) and the TLS handshake completed with no client certificate at all (SSL_get_peer_certificate() returns NULL), nginx logs 'client sent no required SSL certificate', sends this '-ERR' line, and closes the connection.

Source

Thrown at src/mail/ngx_mail_pop3_module.c:60

    ngx_string("EXTERNAL"),
    ngx_null_string   /* NONE */
};


static ngx_mail_protocol_t  ngx_mail_pop3_protocol = {
    ngx_string("pop3"),
    ngx_string("\x04pop3"),
    { 110, 995, 0, 0 },
    NGX_MAIL_POP3_PROTOCOL,

    ngx_mail_pop3_init_session,
    ngx_mail_pop3_init_protocol,
    ngx_mail_pop3_parse_command,
    ngx_mail_pop3_auth_state,

    ngx_string("-ERR internal server error" CRLF),
    ngx_string("-ERR SSL certificate error" CRLF),
    ngx_string("-ERR No required SSL certificate" CRLF)
};


static ngx_command_t  ngx_mail_pop3_commands[] = {

    { ngx_string("pop3_capabilities"),
      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
      ngx_mail_capabilities,
      NGX_MAIL_SRV_CONF_OFFSET,
      offsetof(ngx_mail_pop3_srv_conf_t, capabilities),
      NULL },

    { ngx_string("pop3_auth"),
      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
      ngx_conf_set_bitmask_slot,
      NGX_MAIL_SRV_CONF_OFFSET,
      offsetof(ngx_mail_pop3_srv_conf_t, auth_methods),
      &ngx_mail_pop3_auth_methods },

View on GitHub (pinned to 3f6f7824d4)

Solutions

  1. Configure the mail client to present a client certificate for this account (Thunderbird: certificate management per account; openssl s_client for scripted checks).
  2. Confirm the server advertises acceptable CAs (ssl_client_certificate) so clients actually prompt/send the cert.
  3. If the requirement is softer than 'mandatory', use 'ssl_verify_client optional' — absent certs are then allowed and only bad certs are rejected (error 2309 path).
  4. After policy changes, tell clients to start a fresh TLS session (no resumption) — nginx already removes cached sessions on failure, but stale client state can persist.

Example fix

# before
ssl_client_certificate /etc/nginx/client-ca.pem;
ssl_verify_client on;
# client connects with no client cert -> -ERR No required SSL certificate

# after (option A: give the client a cert)
openssl s_client -connect mail.example.com:995 -CAfile client-ca.pem \
  -cert user@example.com.pem -key user.key -starttls pop3
# after (option B: relax the policy)
#   ssl_verify_client optional;
Defensive patterns

Strategy: validation

Validate before calling

# assert the session will present a cert
import os, ssl
assert os.path.exists('user.pem') and os.path.exists('user.key'), 'mTLS material missing'
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.load_cert_chain('user.pem', 'user.key'); ctx.load_verify_locations('client-ca.pem')
# smoke test: server must not answer with -ERR No required SSL certificate
with socket.create_connection(('mail.example.com', 995), timeout=5) as s:
    tls = ctx.wrap_socket(s, server_hostname='mail.example.com')
    line = tls.recv(256)
    assert not line.startswith(b'-ERR No required'), 'no-cert path hit'

Try / catch

try:
    m = poplib.POP3_SSL('mail.example.com', 995)
    m.user(u)
except poplib.error_proto as e:
    if 'No required SSL certificate' in str(e):
        raise MTLSConfigError('configure a client certificate for this account') from e
    raise

Prevention

When it happens

Trigger: TLS handshake finishes successfully but the client never sends a certificate while ssl_verify_client is 'on'; mail client configured without any client certificate/key; client cert configured but not requested by the TLS layer (wrong profile, e.g. some clients skip the cert when no CA is advertised or when using a stale TLS 1.3 resumption).

Common situations: New mail clients or kiosks onboarded without receiving the required client PKI material; Thunderbird/Outlook account set up before mTLS was enforced; TLS session resumption after the policy change; verify changed from optional to on without notifying users.

Understand the failure class

Related errors


AI-assisted analysis of nginx/nginx@3f6f7824d4 (2026-08-22). Data as JSON: /api/errors/c0833b18d7026086. Report an issue: GitHub.