nginx/nginx · error

NGX_LOG_ALERT

NGX_LOG_ALERT

Error message

unexpected secret len: %uz

What it means

In the set-encryption-secret path, nginx copies the secret handed over by the SSL library into the fixed-size buffer peer_secret->secret.data; if secret_len exceeds that size it logs ALERT 'unexpected secret len: %uz' and the handshake fails. Standard suites never exceed the buffer (SHA-384 secrets are 48 bytes), so a hit means the library emitted an unexpected secret length - almost always a build/runtime mismatch between nginx and its SSL library, or a nonstandard provider altering key derivation.

Source

Thrown at src/event/quic/ngx_event_quic_protection.c:689

    ngx_quic_md_t        key;
    ngx_quic_hkdf_t      seq[3];
    ngx_quic_secret_t   *peer_secret;
    ngx_quic_ciphers_t   ciphers;

    peer_secret = is_write ? &keys->secrets[level].server
                           : &keys->secrets[level].client;

    keys->cipher = SSL_CIPHER_get_id(cipher);

    key_len = ngx_quic_ciphers(keys->cipher, &ciphers);

    if (key_len == NGX_ERROR) {
        ngx_ssl_error(NGX_LOG_INFO, log, 0, "unexpected cipher");
        return NGX_ERROR;
    }

    if (sizeof(peer_secret->secret.data) < secret_len) {
        ngx_log_error(NGX_LOG_ALERT, log, 0,
                      "unexpected secret len: %uz", secret_len);
        return NGX_ERROR;
    }

    peer_secret->secret.len = secret_len;
    ngx_memcpy(peer_secret->secret.data, secret, secret_len);

    key.len = key_len;
    peer_secret->iv.len = NGX_QUIC_IV_LEN;
    peer_secret->hp.len = key_len;

    secret_str.len = secret_len;
    secret_str.data = (u_char *) secret;

    ngx_quic_hkdf_set(&seq[0], "tls13 quic key", &key, &secret_str);
    ngx_quic_hkdf_set(&seq[1], "tls13 quic iv", &peer_secret->iv, &secret_str);
    ngx_quic_hkdf_set(&seq[2], "tls13 quic hp", &peer_secret->hp, &secret_str);

View on GitHub (pinned to 3f6f7824d4)

Solutions

  1. Confirm the loaded library matches the build (ldd, nginx -V) and fix rpath or library paths
  2. Rebuild nginx in the target environment against the exact SSL library it will load
  3. If a custom provider is in play, verify its secret sizes against RFC 8446/9001 suites
Defensive patterns

Strategy: validation

Validate before calling

nginx -V 2>&1 | grep 'built with OpenSSL'
ldd "$(command -v nginx)" | grep -E 'libssl|libcrypto'
# the two must name the same library family/version

Prevention

When it happens

Trigger: nginx running against a different OpenSSL family than it was compiled with; custom ciphers or FIPS providers with altered secret sizes.

Common situations: Library swaps via LD_LIBRARY_PATH after deployment; containers where the base image OpenSSL changed under a copied nginx binary.

Related errors


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