elastic/elasticsearch · error · SslConfigException

no cipher suites configured in [{}]

Error message

no cipher suites configured in [{}]

What it means

Sibling of 829 for ciphers: after resolving ssl.cipher_suites (with defaults), the loader requires a non-null non-empty list. The error message names the exact setting key (prefix + "cipher_suites").

Source

Thrown at libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/SslConfigurationLoader.java:322

        final List<X509Field> trustRestrictionsX509Fields = resolveListSetting(
            TRUST_RESTRICTIONS_X509_FIELDS,
            X509Field::parseForRestrictedTrust,
            defaultRestrictedTrustFields
        );
        final long handshakeTimeoutMillis = resolveSetting(
            HANDSHAKE_TIMEOUT,
            s -> TimeValue.parseTimeValue(s, HANDSHAKE_TIMEOUT),
            DEFAULT_HANDSHAKE_TIMEOUT
        ).millis();

        final SslKeyConfig keyConfig = buildKeyConfig(basePath);
        final SslTrustConfig trustConfig = buildTrustConfig(basePath, verificationMode, keyConfig, Set.copyOf(trustRestrictionsX509Fields));

        if (protocols == null || protocols.isEmpty()) {
            throw new SslConfigException("no protocols configured in [" + settingPrefix + PROTOCOLS + "]");
        }
        if (ciphers == null || ciphers.isEmpty()) {
            throw new SslConfigException("no cipher suites configured in [" + settingPrefix + CIPHERS + "]");
        }
        final boolean isExplicitlyConfigured = hasSettings(settingPrefix);
        return new SslConfiguration(
            settingPrefix,
            isExplicitlyConfigured,
            trustConfig,
            keyConfig,
            verificationMode,
            clientAuth,
            ciphers,
            protocols,
            handshakeTimeoutMillis
        );
    }

    protected SslTrustConfig buildTrustConfig(
        Path basePath,
        SslVerificationMode verificationMode,

View on GitHub (pinned to db6a809a66)

Solutions

  1. Remove the empty cipher_suites setting so DEFAULT_CIPHERS applies.
  2. Populate the list with at least one strong cipher suite recognised by the JVM.
  3. Cross-check cipher names against the JVM's supported suites: SSLSocket.getSupportedCipherSuites().

Example fix

# before
xpack.security.http.ssl.cipher_suites: []
# after (omit, or set explicitly)
xpack.security.http.ssl.cipher_suites: [ "TLS_AES_256_GCM_SHA384", "TLS_AES_128_GCM_SHA256" ]
Defensive patterns

Strategy: validation

Validate before calling

List<String> resolveCiphersSafely(SslConfigurationLoader loader) {
    List<String> c = loader.resolveListSetting("cipher_suites", Function.identity(), SslConfigurationLoader.DEFAULT_CIPHERS);
    if (c == null || c.isEmpty()) return SslConfigurationLoader.DEFAULT_CIPHERS;
    return c;
}

Prevention

When it happens

Trigger: ssl.cipher_suites is explicitly set to an empty list, or a custom loader nulls out DEFAULT_CIPHERS.

Common situations: Operator sets cipher_suites: [] intending to use 'all' ciphers; templated config that conditionally renders an empty list; misunderstanding that an empty value is not the same as 'use defaults'.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/764562d1a1d63bc9. Report an issue: GitHub.