apache/hadoop · error · IOException

Credential {} does not exist in {}

Error message

Credential {} does not exist in {}

What it means

Thrown by UserProvider.deleteCredentialEntry when no credential with the given alias exists in the current user's credentials map (provider URI user:///). UserProvider keeps credentials in-memory on the UserGroupInformation object, so an alias only exists if it was created earlier in the same process/session and flushed to the UGI. Deleting an alias that was never created, or that lived in a different provider, always hits this IOException.

Source

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

      throws IOException {
    Text nameT = new Text(name);
    if (credentials.getSecretKey(nameT) != null) {
      throw new IOException("Credential " + name + 
          " already exists in " + this);
    }
    credentials.addSecretKey(new Text(name), 
        new String(credential).getBytes(StandardCharsets.UTF_8));
    return new CredentialEntry(name, credential);
  }

  @Override
  public synchronized void deleteCredentialEntry(String name) throws IOException {
    byte[] cred = credentials.getSecretKey(new Text(name));
    if (cred != null) {
      credentials.removeSecretKey(new Text(name));
    }
    else {
      throw new IOException("Credential " + name + 
          " does not exist in " + this);
    }
  }

  @Override
  public String toString() {
    return SCHEME_NAME + ":///";
  }

  @Override
  public synchronized void flush() {
    user.addCredentials(credentials);
  }

  public static class Factory extends CredentialProviderFactory {

    @Override
    public CredentialProvider createProvider(URI providerName,

View on GitHub (pinned to 2add963021)

Solutions

  1. List the entries first (`hadoop credential list -provider user:///`) and confirm the exact alias spelling before deleting
  2. Guard the delete in code: call provider.getCredentialEntry(alias) and only call deleteCredentialEntry when it returns non-null
  3. If the credential must survive JVM restarts, use a persistent provider (jceks://path/file.jceks or kms://...) instead of user:///
  4. In scripts, wrap the delete in try/catch IOException and treat 'does not exist' as a non-fatal idempotent case

Example fix

// before
provider.deleteCredentialEntry(alias); // IOException if absent

// after
if (provider.getCredentialEntry(alias) != null) {
  provider.deleteCredentialEntry(alias);
} else {
  LOG.warn("Credential {} already absent, skipping delete", alias);
}
Defensive patterns

Strategy: validation

Validate before calling

CredentialEntry entry = provider.getCredentialEntry(alias);
if (entry != null) {
  provider.deleteCredentialEntry(alias);
} else {
  LOG.warn("Credential {} not present in {}; nothing to delete", alias, provider);
}

Try / catch

try {
  provider.deleteCredentialEntry(alias);
} catch (IOException e) {
  if (e.getMessage().contains("does not exist")) {
    // idempotent delete: treat as success for scripts
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling deleteCredentialEntry(name) directly, or `hadoop credential delete <alias> -provider user:///`, when credentials.getSecretKey(new Text(name)) returns null: misspelled alias, entry never created in this JVM, or entry lives in a jceks:// or kms:// provider instead.

Common situations: Automation scripts that delete a credential without creating it first; alias typos between create and delete steps; expecting user:/// to persist across process restarts (it does not — it is in-memory per UGI); mixing user:/// with persistent providers and deleting from the wrong one.

Related errors


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