{"record":{"id":"bc21e9d30031fea9","repo":"apache/hadoop","slug":"credential-alias-already-exists-in-thi","errorCode":null,"errorMessage":"Credential \" + alias + \" already exists in \" + this","messagePattern":"Credential \" \\+ alias \\+ \" already exists in \" \\+ this","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/AbstractJavaKeyStoreProvider.java","lineNumber":234,"sourceCode":"          list.add(alias);\n        }\n      } catch (KeyStoreException e) {\n        throw new IOException(\"Can't get alias \" + alias + \" from \"\n            + getPathAsString(), e);\n      }\n      return list;\n    } finally {\n      readLock.unlock();\n    }\n  }\n\n  @Override\n  public CredentialEntry createCredentialEntry(String alias, char[] credential)\n      throws IOException {\n    writeLock.lock();\n    try {\n      if (keyStore.containsAlias(alias)) {\n        throw new IOException(\"Credential \" + alias + \" already exists in \"\n            + this);\n      }\n      return innerSetCredential(alias, credential);\n    } catch (KeyStoreException e) {\n      throw new IOException(\"Problem looking up credential \" + alias + \" in \"\n          + this, e);\n    } finally {\n      writeLock.unlock();\n    }\n  }\n\n  @Override\n  public void deleteCredentialEntry(String name) throws IOException {\n    writeLock.lock();\n    try {\n      try {\n        if (keyStore.containsAlias(name)) {\n          keyStore.deleteEntry(name);","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/alias/AbstractJavaKeyStoreProvider.java#L216-L252","documentation":"createCredentialEntry() refuses to overwrite: the keystore already contains an entry with this exact alias. This is by design so secrets are not silently clobbered; to change a value you must delete the entry first, then create it again.","triggerScenarios":"Calling provider.createCredentialEntry(alias, material) when keyStore.containsAlias(alias) is true; running 'hadoop credential create <alias> -provider ...' a second time; provisioning scripts that run create on every deploy.","commonSituations":"Re-running bootstrap scripts that assume create is an upsert; rotating a password by re-creating the alias without deleting it first; two admins writing the same alias name.","solutions":["Delete the existing entry first: hadoop credential delete <alias> -provider <path> (or provider.deleteCredentialEntry(alias)), then create","Check before writing: provider.getCredentialEntry(alias) != null or 'hadoop credential list -provider <path>'","Make provisioning scripts idempotent: list aliases, delete-if-present, then create"],"exampleFix":"// before\nprovider.createCredentialEntry(alias, newPassword); // IOException: already exists\n\n// after\nif (provider.getCredentialEntry(alias) != null) {\n  provider.deleteCredentialEntry(alias);\n  provider.flush();\n}\nprovider.createCredentialEntry(alias, newPassword);\nprovider.flush();","handlingStrategy":"validation","validationCode":"// Check-before-create (read is cheap and non-mutating)\nif (provider.getCredentialEntry(alias) != null) {\n  provider.deleteCredentialEntry(alias);\n  provider.flush();\n}\nprovider.createCredentialEntry(alias, material);\nprovider.flush();","typeGuard":"boolean aliasMissing(CredentialProvider p, String alias) throws IOException {\n  return p.getCredentialEntry(alias) == null;\n}","tryCatchPattern":"try {\n  provider.createCredentialEntry(alias, material);\n} catch (IOException ex) {\n  if (ex.getMessage() != null && ex.getMessage().contains(\"already exists\")) {\n    provider.deleteCredentialEntry(alias);\n    provider.flush();\n    provider.createCredentialEntry(alias, material); // deliberate overwrite\n    provider.flush();\n  } else { throw ex; }\n}","preventionTips":["Make credential bootstrap scripts idempotent: list -> delete-if-present -> create -> flush","Prefer explicit delete+create for rotation; never assume upsert semantics from the provider API","Audit aliases with 'hadoop credential list' before re-running provisioning"],"tags":["hadoop","credential-provider","keystore","alias-exists","jceks"],"backgroundTag":"duplicate-keystore-alias","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}