apache/hadoop · warning · IOException

Credential " + name + " does not exist in " + this

Error message

Credential " + name + " does not exist in " + this

What it means

deleteCredentialEntry() only deletes aliases that exist: containsAlias(name) returned false, so Hadoop refuses the delete. The alias is misspelled, already deleted, or the provider path resolves to a different keystore file than the one holding the credential.

Source

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

      }
      return innerSetCredential(alias, credential);
    } catch (KeyStoreException e) {
      throw new IOException("Problem looking up credential " + alias + " in "
          + this, e);
    } finally {
      writeLock.unlock();
    }
  }

  @Override
  public void deleteCredentialEntry(String name) throws IOException {
    writeLock.lock();
    try {
      try {
        if (keyStore.containsAlias(name)) {
          keyStore.deleteEntry(name);
        } else {
          throw new IOException("Credential " + name + " does not exist in "
              + this);
        }
      } catch (KeyStoreException e) {
        throw new IOException("Problem removing " + name + " from " + this, e);
      }
      changed = true;
    } finally {
      writeLock.unlock();
    }
  }

  CredentialEntry innerSetCredential(String alias, char[] material)
      throws IOException {
    writeLock.lock();
    try {
      keyStore.setKeyEntry(alias,
          new SecretKeySpec(new String(material).getBytes(StandardCharsets.UTF_8),
              getAlgorithm()), password, null);

View on GitHub (pinned to 2add963021)

Solutions

  1. List what is actually there: hadoop credential list -provider <path>, and compare alias spelling exactly
  2. Confirm the provider URI used for delete is byte-identical to the one used for create
  3. Make deletes idempotent: treat 'does not exist' as success instead of failing the run

Example fix

// before
provider.deleteCredentialEntry(name);

// after
if (provider.getCredentialEntry(name) == null) {
  LOG.info("Alias {} already absent; nothing to do", name);
} else {
  provider.deleteCredentialEntry(name);
  provider.flush();
}
Defensive patterns

Strategy: validation

Validate before calling

// Idempotent delete: confirm the alias exists first
boolean exists = provider.getAliases().contains(name);
if (exists) {
  provider.deleteCredentialEntry(name);
  provider.flush();
}

Type guard

boolean aliasExists(CredentialProvider p, String name) throws IOException {
  return p.getAliases().contains(name);
}

Try / catch

try {
  provider.deleteCredentialEntry(name);
} catch (IOException ex) {
  if (ex.getMessage() != null && ex.getMessage().contains("does not exist")) {
    LOG.info("Alias {} already gone - treating delete as success", name);
  } else { throw ex; }
}

Prevention

When it happens

Trigger: provider.deleteCredentialEntry(name) for an alias not in the store; 'hadoop credential delete <alias> -provider <path>' with a typo or wrong-case alias; create and delete executed against different provider URIs; store silently recreated empty because the password defaulted to 'none'.

Common situations: Retry logic in cleanup scripts deleting an alias that a previous run already removed; environments (dev/prod) with different keystore paths; case-sensitive alias mismatch.

Related errors


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