{"record":{"id":"efaaede6afaf56bd","repo":"SonarSource/sonarqube","slug":"failed-to-setup-ssl-context-on-es-client-efaaed","errorCode":null,"errorMessage":"Failed to setup SSL context on ES client","messagePattern":"Failed to setup SSL context on ES client","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"server/sonar-server-common/src/main/java/org/sonar/server/es/EsClient.java","lineNumber":344,"sourceCode":"      clientBuilder.addRequestInterceptorFirst((request, entity, context) -> {\n        if (!request.containsHeader(\"Authorization\")) {\n          request.addHeader(\"Authorization\", headerValue);\n        }\n      });\n    }\n    return clientBuilder.build();\n  }\n\n  private static SSLContext buildSslContext(String keyStorePath, @Nullable String keyStorePassword) {\n    try {\n      KeyStore keyStore = KeyStore.getInstance(\"pkcs12\");\n      try (InputStream is = Files.newInputStream(Paths.get(keyStorePath))) {\n        keyStore.load(is, keyStorePassword == null ? null : keyStorePassword.toCharArray());\n      }\n      SSLContextBuilder sslBuilder = SSLContexts.custom().loadTrustMaterial(keyStore, null);\n      return sslBuilder.build();\n    } catch (IOException | GeneralSecurityException e) {\n      throw new IllegalStateException(\"Failed to setup SSL context on ES client\", e);\n    }\n  }\n\n  <R> R execute(EsRequestExecutor<R> executor) {\n    return execute(executor, () -> \"\");\n  }\n\n  <R> R execute(EsRequestExecutor<R> executor, Supplier<String> requestDetails) {\n    Profiler profiler = Profiler.createIfTrace(EsClient.LOGGER).start();\n    try {\n      return executor.execute();\n    } catch (Exception e) {\n      throw new ElasticsearchException(\"Fail to execute es request\" + requestDetails.get(), e);\n    } finally {\n      if (profiler.isTraceEnabled()) {\n        profiler.stopTrace(requestDetails.get());\n      }\n    }","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-server-common/src/main/java/org/sonar/server/es/EsClient.java#L326-L362","documentation":"EsClient.buildSslContext loads a keystore (trust store) from sonar.auth.elasticsearch... keyStorePath and builds an SSLContext for the Elasticsearch REST client. Any IOException (missing/unreadable file) or GeneralSecurityException (bad password, corrupted keystore, unsupported algorithm) is wrapped in an IllegalStateException, as TLS setup is mandatory for a secured ES connection.","triggerScenarios":"sonar.cluster.es.ssl.keystorePath (or equivalent) points to a non-existent or unreadable file; wrong keystore password; keystore in an unsupported format/corrupted; missing JCE algorithm.","commonSituations":"K8s/containers where the keystore secret was not mounted; password mismatch after rotation; PKCS12 vs JKS format confusion; relative paths resolving to the wrong working directory.","solutions":["Verify the keyStorePath exists and is readable by the SonarQube process user (absolute path recommended).","Confirm the keystore password is correct and matches the file.","Validate the keystore with `keytool -list -keystore <file>`; recreate it if corrupted.","Ensure the keystore format is supported (JKS/PKCS12) and consistent with the loader.","Check that the secret/config mount is present in containerized deployments."],"exampleFix":"// before (sonar.properties)\nsonar.cluster.es.ssl.keystorePath=es-keystore.jks\n// after\nsonar.cluster.es.ssl.keystorePath=/opt/sonarqube/conf/es-keystore.p12","handlingStrategy":"validation","validationCode":"Path ks = Paths.get(keyStorePath);\nif (!Files.isRegularFile(ks) || !Files.isReadable(ks)) {\n  throw new IllegalStateException(\"ES keystore missing or unreadable: \" + ks);\n}\n// additionally verify with:\n// keytool -list -keystore es-keystore.p12 -storepass <password>","typeGuard":null,"tryCatchPattern":"try {\n  EsClient client = esClientFactory.build();\n} catch (IllegalStateException e) {\n  if (\"Failed to setup SSL context on ES client\".equals(e.getMessage())) {\n    throw new ConfigurationException(\"Check sonar.cluster.es.ssl.keystorePath/password\", e);\n  }\n  throw e;\n}","preventionTips":["Mount keystore secrets reliably in containers/K8s and verify at startup.","Use absolute paths for keyStorePath.","Verify keystores with keytool after each rotation.","Keep format (JKS/PKCS12) consistent with tooling."],"tags":["elasticsearch","ssl","keystore"],"backgroundTag":"ssl-context-setup-failed","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}