apache/hadoop · error · IOException

Can't recover credential " + alias + " from " +…

Error message

Can't recover credential " + alias + " from " + getPathAsString()

What it means

Thrown when KeyStore.getKey() raises UnrecoverableKeyException inside getCredentialEntry: the password used to open the entry does not match the password the entry was stored with. For Hadoop keystore providers the store password comes from HADOOP_CREDSTORE_PASSWORD, the file named by hadoop.security.credential.store.password, or the default 'none'. In practice this almost always means the keystore password is wrong, not that the data is unrecoverable.

Solutions

  1. Export the correct store password: HADOOP_CREDSTORE_PASSWORD=<pw> (or configure hadoop.security.credential.store.password to a readable password file)
  2. Verify with an independent tool that the password is right: keytool -list -keystore <file> -storetype jceks -storepass <pw>
  3. Confirm the provider is picking the password source you think (provider.needsPassword() / noPasswordWarning() log output)
  4. If the password is truly lost, there is no recovery: recreate the keystore and re-add every credential
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast if the store password is not resolvable before any entry read
AbstractJavaKeyStoreProvider ajkp = (AbstractJavaKeyStoreProvider) provider;
if (ajkp.needsPassword()) {
  throw new IllegalStateException(
      "Set HADOOP_CREDSTORE_PASSWORD or " +
      AbstractJavaKeyStoreProvider.CREDENTIAL_PASSWORD_FILE_KEY);
}

Try / catch

try {
  provider.getCredentialEntry(alias);
} catch (IOException ex) {
  if (ex.getCause() instanceof java.security.UnrecoverableKeyException) {
    // wrong store password: prompt/reconfigure HADOOP_CREDSTORE_PASSWORD, never brute-force in a loop
  } else { throw ex; }
}

Prevention

When it happens

Trigger: Reading an alias with HADOOP_CREDSTORE_PASSWORD unset or different from the one used when the store was created; the password-file property pointing at a missing/stale file so the default 'none' is silently used; the store was created by another tool (keytool) or another team with a different password.

Common situations: Password env var exported in the admin's shell but not in the service/CI environment; store created with a real password then read in a session where only 'none' defaults apply; shared cluster keystore rotated without re-exporting the variable.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/2b3ec864e2017c5f. Report an issue: GitHub.

Appendix: source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/AbstractJavaKeyStoreProvider.java:191

  @Override
  public CredentialEntry getCredentialEntry(String alias)
      throws IOException {
    readLock.lock();
    try {
      SecretKeySpec key = null;
      try {
        if (!keyStore.containsAlias(alias)) {
          return null;
        }
        key = (SecretKeySpec) keyStore.getKey(alias, password);
      } catch (KeyStoreException e) {
        throw new IOException("Can't get credential " + alias + " from "
            + getPathAsString(), e);
      } catch (NoSuchAlgorithmException e) {
        throw new IOException("Can't get algorithm for credential " + alias
            + " from " + getPathAsString(), e);
      } catch (UnrecoverableKeyException e) {
        throw new IOException("Can't recover credential " + alias + " from "
            + getPathAsString(), e);
      }
      return new CredentialEntry(alias, bytesToChars(key.getEncoded()));
    } finally {
      readLock.unlock();
    }
  }

  public static char[] bytesToChars(byte[] bytes) throws IOException {
    String pass;
    pass = new String(bytes, StandardCharsets.UTF_8);
    return pass.toCharArray();
  }

  @Override
  public List<String> getAliases() throws IOException {
    readLock.lock();
    try {

View on GitHub (pinned to 2add963021)