{"record":{"id":"c34e0d4536da28b0","repo":"apache/hadoop","slug":"credential-does-not-exist-in","errorCode":null,"errorMessage":"Credential {} does not exist in {}","messagePattern":"Credential (.+?) does not exist in (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/UserProvider.java","lineNumber":84,"sourceCode":"      throws IOException {\n    Text nameT = new Text(name);\n    if (credentials.getSecretKey(nameT) != null) {\n      throw new IOException(\"Credential \" + name + \n          \" already exists in \" + this);\n    }\n    credentials.addSecretKey(new Text(name), \n        new String(credential).getBytes(StandardCharsets.UTF_8));\n    return new CredentialEntry(name, credential);\n  }\n\n  @Override\n  public synchronized void deleteCredentialEntry(String name) throws IOException {\n    byte[] cred = credentials.getSecretKey(new Text(name));\n    if (cred != null) {\n      credentials.removeSecretKey(new Text(name));\n    }\n    else {\n      throw new IOException(\"Credential \" + name + \n          \" does not exist in \" + this);\n    }\n  }\n\n  @Override\n  public String toString() {\n    return SCHEME_NAME + \":///\";\n  }\n\n  @Override\n  public synchronized void flush() {\n    user.addCredentials(credentials);\n  }\n\n  public static class Factory extends CredentialProviderFactory {\n\n    @Override\n    public CredentialProvider createProvider(URI providerName,","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/UserProvider.java#L66-L102","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["List the entries first (`hadoop credential list -provider user:///`) and confirm the exact alias spelling before deleting","Guard the delete in code: call provider.getCredentialEntry(alias) and only call deleteCredentialEntry when it returns non-null","If the credential must survive JVM restarts, use a persistent provider (jceks://path/file.jceks or kms://...) instead of user:///","In scripts, wrap the delete in try/catch IOException and treat 'does not exist' as a non-fatal idempotent case"],"exampleFix":"// before\nprovider.deleteCredentialEntry(alias); // IOException if absent\n\n// after\nif (provider.getCredentialEntry(alias) != null) {\n  provider.deleteCredentialEntry(alias);\n} else {\n  LOG.warn(\"Credential {} already absent, skipping delete\", alias);\n}","handlingStrategy":"validation","validationCode":"CredentialEntry entry = provider.getCredentialEntry(alias);\nif (entry != null) {\n  provider.deleteCredentialEntry(alias);\n} else {\n  LOG.warn(\"Credential {} not present in {}; nothing to delete\", alias, provider);\n}","typeGuard":null,"tryCatchPattern":"try {\n  provider.deleteCredentialEntry(alias);\n} catch (IOException e) {\n  if (e.getMessage().contains(\"does not exist\")) {\n    // idempotent delete: treat as success for scripts\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always list credentials (`hadoop credential list -provider ...`) before scripted deletes","Use persistent providers (jceks/kms) for anything created in one process and deleted in another","Standardize alias naming in automation to avoid typos between create and delete"],"tags":["credentials","credential-provider","security","hadoop","user-provider"],"backgroundTag":"credential-not-found","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}