How to enable post-quantum TLS (X25519MLKEM768) on nginx

Updated:

Chrome (since version 131) and Firefox already offer the hybrid key exchange X25519MLKEM768 in every HTTPS connection. If your server accepts it, the session keys are protected against a future quantum computer. If it does not, the browser falls back to plain X25519 and the traffic can be recorded today and decrypted later (harvest now, decrypt later).

1. Check your OpenSSL version

nginx gets its TLS from the OpenSSL library it was built against. ML-KEM arrived in OpenSSL 3.5.

nginx -V 2>&1 | grep -o 'OpenSSL [0-9.]*'
openssl version

If either shows 3.0, 3.1, 3.2, 3.3 or 3.4, nginx cannot negotiate ML-KEM no matter what you put in the config. Ubuntu 22.04 and 24.04 ship OpenSSL 3.0; Debian 13 (trixie) ships 3.5. Your options are to upgrade the OS, use an nginx build linked against OpenSSL 3.5, or put a post-quantum capable proxy or CDN in front (see the other servers guide).

2. Configure nginx

With OpenSSL 3.5, X25519MLKEM768 is in the default group list, so nginx's default ssl_ecdh_curve auto already offers it. The common mistake is an explicit curve list copied from an old hardening guide, which silently removes it. Make the list explicit and put the hybrid group first:

server {
    listen 443 ssl;
    http2 on;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ecdh_curve X25519MLKEM768:X25519:prime256v1;
    # ... certificates and the rest of your config
}

Also look in included files such as /etc/letsencrypt/options-ssl-nginx.conf for another ssl_ecdh_curve line. Then:

nginx -t && systemctl reload nginx

3. Verify

With an OpenSSL 3.5 client:

openssl s_client -connect example.com:443 -groups X25519MLKEM768 </dev/null 2>/dev/null | grep -i group

You should see X25519MLKEM768 as the negotiated group. Or run the free scan: grade A means TLS 1.3 with a hybrid post-quantum key exchange.

Watch out for

Scan your site now, free