{"record":{"id":"f8356dd8608ecd49","repo":"elastic/elasticsearch","slug":"no-ssl-tls-protocols-have-been-configured","errorCode":null,"errorMessage":"no SSL/TLS protocols have been configured","messagePattern":"no SSL/TLS protocols have been configured","errorType":"exception","errorClass":"SslConfigException","httpStatus":null,"severity":"error","filePath":"libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/SslConfiguration.java","lineNumber":149,"sourceCode":"    public SSLContext createSslContext() {\n        final X509ExtendedKeyManager keyManager = keyConfig.createKeyManager();\n        final X509ExtendedTrustManager trustManager = trustConfig.createTrustManager();\n        try {\n            SSLContext sslContext = SSLContext.getInstance(contextProtocol());\n            sslContext.init(new X509ExtendedKeyManager[] { keyManager }, new X509ExtendedTrustManager[] { trustManager }, null);\n            return sslContext;\n        } catch (GeneralSecurityException e) {\n            throw new SslConfigException(\"cannot create ssl context\", e);\n        }\n    }\n\n    /**\n     * Picks the best (highest security / most recent standard) SSL/TLS protocol (/version) that is supported by the\n     * {@link #supportedProtocols() configured protocols}.\n     */\n    private String contextProtocol() {\n        if (supportedProtocols.isEmpty()) {\n            throw new SslConfigException(\"no SSL/TLS protocols have been configured\");\n        }\n        for (Entry<String, String> entry : ORDERED_PROTOCOL_ALGORITHM_MAP.entrySet()) {\n            if (supportedProtocols.contains(entry.getKey())) {\n                return entry.getValue();\n            }\n        }\n        throw new SslConfigException(\n            \"no supported SSL/TLS protocol was found in the configured supported protocols: \" + supportedProtocols\n        );\n    }\n}\n","sourceCodeStart":131,"sourceCodeEnd":161,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/ssl-config/src/main/java/org/elasticsearch/common/ssl/SslConfiguration.java#L131-L161","documentation":"Defensive guard inside the private contextProtocol(): if supportedProtocols is empty when picking the SSLContext algorithm, no algorithm can be selected. Because the constructor (error 823) already rejects empty protocols and the field is immutable, this branch is effectively unreachable through the public API.","triggerScenarios":"Only reachable via reflection or a future code change that bypasses the constructor's empty-list check. In normal flows the constructor precondition fires first.","commonSituations":"Subclassing SslConfiguration in a non-standard way; a future refactor that adds a setter; tests using reflection to clear the field.","solutions":["Treat this as a programmer error — ensure the SslConfiguration constructor always receives a non-empty protocols list.","If seen in production, audit for reflective access or serialization paths that reconstruct the object without the constructor.","Report as a bug if reached via documented APIs."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the constructor invariant holds; this internal branch should be unreachable.\nObjects.requireNonNull(protocols, \"protocols\");\nif (protocols.isEmpty()) throw new IllegalStateException(\"protocols must not be empty before SslConfiguration is built\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct SslConfiguration with empty protocols; the constructor already enforces this.","Treat sightings of this error as a bug — investigate reflective or deserialised reconstruction."],"tags":["ssl","protocols","internal","defensive"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}