{"record":{"id":"b427934ce7b179e5","repo":"apache/hadoop","slug":"could-not-load-truststore-keep-using-existing-one","errorCode":null,"errorMessage":"Could not load truststore (keep using existing one) : ","messagePattern":"Could not load truststore \\(keep using existing one\\) : ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/ReloadingX509TrustManager.java","lineNumber":120,"sourceCode":"  }\n\n  private static final X509Certificate[] EMPTY = new X509Certificate[0];\n  @Override\n  public X509Certificate[] getAcceptedIssuers() {\n    X509Certificate[] issuers = EMPTY;\n    X509TrustManager tm = trustManagerRef.get();\n    if (tm != null) {\n      issuers = tm.getAcceptedIssuers();\n    }\n    return issuers;\n  }\n\n  public ReloadingX509TrustManager loadFrom(Path path) {\n    try {\n      this.trustManagerRef.set(loadTrustManager(path));\n    } catch (Exception ex) {\n      // The Consumer.accept interface forces us to convert to unchecked\n      throw new RuntimeException(RELOAD_ERROR_MESSAGE, ex);\n    }\n    return this;\n  }\n\n  X509TrustManager loadTrustManager(Path path)\n  throws IOException, GeneralSecurityException {\n    X509TrustManager trustManager = null;\n    KeyStore ks = KeyStore.getInstance(type);\n    InputStream in = Files.newInputStream(path);\n    try {\n      ks.load(in, (password == null) ? null : password.toCharArray());\n      LOG.debug(\"Loaded truststore '\" + path + \"'\");\n    } finally {\n      in.close();\n    }\n\n    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(\n        SSLFactory.TRUST_MANAGER_SSLCERTIFICATE);","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/ssl/ReloadingX509TrustManager.java#L102-L138","documentation":"ReloadingX509TrustManager.loadFrom wraps any failure of loadTrustManager (IO or security exception while opening/loading the truststore file) in a RuntimeException with the message 'Could not load truststore (keep using existing one) : ' — the previous trust manager stays active. The file-monitor timer in FileBasedKeyStoresFactory catches and logs this (LOG.error) instead of propagating, so most users see it as a log line during certificate reload.","triggerScenarios":"The truststore file on disk changed and the reload timer (interval from ssl.<mode>.stores.reload.interval, default 10s) tried to reload it while it was corrupt, truncated mid-copy, unreadable, or the password no longer matched.","commonSituations":"Certificate rotation scripts writing the new truststore in place (torn read); file replaced with a keystore generated under a different password; chmod/chown during deployment making the file unreadable for the monitor; NFS latency exposing partial files.","solutions":["Write the new truststore to a temp file in the same directory, verify it, then atomically rename over the old one","Confirm the new file's password and type match the configured ssl.<mode>.truststore.password/.type","Check file ownership/permissions for the monitoring service user","If you call loadFrom directly, catch RuntimeException, inspect getCause(), and keep serving on the old truststore until the file is fixed"],"exampleFix":"# before: rotation script writes in place\ncp new-truststore.jks /etc/security/tls/truststore.jks  # torn read possible\n\n# after: atomic replace\ncp new-truststore.jks /etc/security/tls/.truststore.jks.tmp\nkeytool -list -keystore /etc/security/tls/.truststore.jks.tmp -storepass \"$PW\" >/dev/null\nmv /etc/security/tls/.truststore.jks.tmp /etc/security/tls/truststore.jks","handlingStrategy":"fallback","validationCode":"// if you invoke reload yourself, validate the file first\nKeyStore probe = KeyStore.getInstance(type);\ntry (InputStream in = Files.newInputStream(path)) {\n  probe.load(in, password.toCharArray());\n} catch (Exception e) {\n  LOG.warn(\"Refusing to reload from unparseable truststore {}: {}\", path, e.getMessage());\n  return; // keep current trust manager\n}\ntrustManager.loadFrom(path);","typeGuard":null,"tryCatchPattern":"try {\n  trustManager.loadFrom(newPath);\n} catch (RuntimeException e) {\n  // previous truststore remains active; inspect cause and alert\n  LOG.error(\"Truststore reload failed, continuing with existing truststore\", e.getCause());\n}","preventionTips":["Deploy truststores atomically (write temp + rename) so reloads never read partial files","Keep truststore password stable across rotations or update configuration in the same change","Monitor for the 'Could not load truststore' log line and page on it during rotation windows"],"tags":["ssl","tls","truststore","reload","cert-rotation","hadoop"],"backgroundTag":"config-reload-failure","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}