Skip to content
ecdsa.com
Python ssl module (OpenSSL, security level 2)Python cryptography

Error message

[SSL: DH_KEY_TOO_SMALL] dh key too small

Followed by a source location such as "(_ssl.c:1082)". curl and other OpenSSL clients print the same reason as "dh key too small".

Python ssl module (OpenSSL, security level 2) — ssl.SSLError, SSL_R_DH_KEY_TOO_SMALL

What it means

The server chose a finite-field Diffie-Hellman (DHE) key exchange with a group smaller than the client accepts, typically 1024 bits. Python 3.10 and later use OpenSSL security level 2, which requires at least 2048-bit DH, so the client aborts the handshake. The server's certificate is not the problem.

Why it happens

How to fix it

  1. 1.

    Confirm the key-exchange size

    Connect once at security level 1 with openssl s_client and read "Server Temp Key".

    bash
    # "Server Temp Key: DH, 1024 bits" confirms the weak group
    openssl s_client -connect legacy.example.com:443 -servername legacy.example.com \
      -cipher 'DEFAULT:@SECLEVEL=1' </dev/null 2>/dev/null | grep 'Server Temp Key'
  2. 2.

    Server owners: use ECDHE or a 2048-bit group

    Prefer ECDHE suites (and TLS 1.3); if DHE is required, configure an RFC 7919 group of at least 2048 bits.

    text
    # nginx: prefer ECDHE; if DHE must stay, use a 2048-bit (or larger) group
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_dhparam /etc/nginx/ffdhe2048.pem;   # RFC 7919 group
  3. 3.

    Temporary workaround: lower the security level for one host

    "DEFAULT:@SECLEVEL=1" in a dedicated context accepts 1024-bit DH for that host only. Keep it off shared or default contexts: it also accepts other weak parameters.

    python
    # Temporary workaround for one legacy host: security level 1 accepts 1024-bit DH
    import ssl, urllib.request
    
    ctx = ssl.create_default_context()
    ctx.set_ciphers("DEFAULT:@SECLEVEL=1")
    urllib.request.urlopen("https://legacy.example.com/", context=ctx)

Related errors

Browse the full signature error database