{"record":{"id":"758389d6541ca3f7","repo":"apache/druid","slug":"user-s-already-exists","errorCode":null,"errorMessage":"User [%s] already exists.","messagePattern":"User \\[(.+?)\\] already exists\\.","errorType":"exception","errorClass":"BasicSecurityDBResourceException","httpStatus":null,"severity":"warning","filePath":"extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/db/updater/CoordinatorBasicAuthenticatorMetadataStorageUpdater.java","lineNumber":376,"sourceCode":"      try {\n        Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY));\n      }\n      catch (InterruptedException ie) {\n        throw new RuntimeException(ie);\n      }\n    }\n    throw new ISE(\"Could not set credentials for user[%s] due to concurrent update contention.\", userName);\n  }\n\n  private boolean createUserOnce(String prefix, String userName)\n  {\n    byte[] oldValue = getCurrentUserMapBytes(prefix);\n    Map<String, BasicAuthenticatorUser> userMap = BasicAuthUtils.deserializeAuthenticatorUserMap(\n        objectMapper,\n        oldValue\n    );\n    if (userMap.get(userName) != null) {\n      throw new BasicSecurityDBResourceException(\"User [%s] already exists.\", userName);\n    } else {\n      userMap.put(userName, new BasicAuthenticatorUser(userName, null));\n    }\n    byte[] newValue = BasicAuthUtils.serializeAuthenticatorUserMap(objectMapper, userMap);\n    return tryUpdateUserMap(prefix, userMap, oldValue, newValue);\n  }\n\n  private boolean deleteUserOnce(String prefix, String userName)\n  {\n    byte[] oldValue = getCurrentUserMapBytes(prefix);\n    Map<String, BasicAuthenticatorUser> userMap = BasicAuthUtils.deserializeAuthenticatorUserMap(\n        objectMapper,\n        oldValue\n    );\n    if (userMap.get(userName) == null) {\n      throw new BasicSecurityDBResourceException(\"User [%s] does not exist.\", userName);\n    } else {\n      userMap.remove(userName);","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/db/updater/CoordinatorBasicAuthenticatorMetadataStorageUpdater.java#L358-L394","documentation":"Thrown as BasicSecurityDBResourceException when createUserOnce detects the requested user already exists in the authenticator user map. The user-creation API enforces uniqueness of user names per authenticator. The exception is surfaced as an HTTP error response to the caller of the user-creation endpoint.","triggerScenarios":"Calling createUser (POST /druid-ext/basic-security/authentication/<authenticator>/users/<userName>) for a userName already present in the stored user map.","commonSituations":"Rerunning an idempotent provisioning script that creates users without a check-first; retrying a create after a network timeout where the first request actually succeeded; two admins creating the same named user concurrently.","solutions":["Check existence first (GET the user) or delete the existing user before recreating","Treat this exception in clients as an idempotency signal and skip creation if the user already exists","Use unique user names in provisioning automation","Catch BasicSecurityDBResourceException in tooling and log it as a non-fatal condition"],"exampleFix":"// before\nclient.createUser(authenticatorName, userName); // 400 if user exists\n// after\nif (client.getUser(authenticatorName, userName).getStatus() == 404) {\n  client.createUser(authenticatorName, userName);\n}","handlingStrategy":"validation","validationCode":"Response r = client.getUser(authenticatorName, userName);\nboolean exists = r.getStatus() == 200;\nif (exists) return; // already created; skip","typeGuard":null,"tryCatchPattern":"try {\n  client.createUser(authenticatorName, userName);\n} catch (ProcessingException | WebApplicationException e) {\n  // BasicSecurityDBResourceException surfaces as an HTTP error response\n  if (responseIndicatesUserAlreadyExists(e)) { /* idempotent skip */ } else throw e;\n}","preventionTips":["Make provisioning scripts idempotent: check-then-create or treat already-exists as success","Use unique, generated user names in automation","Avoid concurrent create calls for the same userName"],"tags":["duplicate-resource","basic-security","user-management"],"backgroundTag":"file-already-exists","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}