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
- Confirm the loaded library matches the build (ldd, nginx -V) and fix rpath or library paths
- Rebuild nginx in the target environment against the exact SSL library it will load
- 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
- Build nginx in the same environment that runs it
- Bake nginx and libssl into one immutable image; never mix release trains
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.