apache/druid · warning · BasicSecurityDBResourceException

User [%s] already exists.

Error message

User [%s] already exists.

What it means

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.

Source

Thrown at extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/db/updater/CoordinatorBasicAuthenticatorMetadataStorageUpdater.java:376

      try {
        Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY));
      }
      catch (InterruptedException ie) {
        throw new RuntimeException(ie);
      }
    }
    throw new ISE("Could not set credentials for user[%s] due to concurrent update contention.", userName);
  }

  private boolean createUserOnce(String prefix, String userName)
  {
    byte[] oldValue = getCurrentUserMapBytes(prefix);
    Map<String, BasicAuthenticatorUser> userMap = BasicAuthUtils.deserializeAuthenticatorUserMap(
        objectMapper,
        oldValue
    );
    if (userMap.get(userName) != null) {
      throw new BasicSecurityDBResourceException("User [%s] already exists.", userName);
    } else {
      userMap.put(userName, new BasicAuthenticatorUser(userName, null));
    }
    byte[] newValue = BasicAuthUtils.serializeAuthenticatorUserMap(objectMapper, userMap);
    return tryUpdateUserMap(prefix, userMap, oldValue, newValue);
  }

  private boolean deleteUserOnce(String prefix, String userName)
  {
    byte[] oldValue = getCurrentUserMapBytes(prefix);
    Map<String, BasicAuthenticatorUser> userMap = BasicAuthUtils.deserializeAuthenticatorUserMap(
        objectMapper,
        oldValue
    );
    if (userMap.get(userName) == null) {
      throw new BasicSecurityDBResourceException("User [%s] does not exist.", userName);
    } else {
      userMap.remove(userName);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. Check existence first (GET the user) or delete the existing user before recreating
  2. Treat this exception in clients as an idempotency signal and skip creation if the user already exists
  3. Use unique user names in provisioning automation
  4. Catch BasicSecurityDBResourceException in tooling and log it as a non-fatal condition

Example fix

// before
client.createUser(authenticatorName, userName); // 400 if user exists
// after
if (client.getUser(authenticatorName, userName).getStatus() == 404) {
  client.createUser(authenticatorName, userName);
}
Defensive patterns

Strategy: validation

Validate before calling

Response r = client.getUser(authenticatorName, userName);
boolean exists = r.getStatus() == 200;
if (exists) return; // already created; skip

Try / catch

try {
  client.createUser(authenticatorName, userName);
} catch (ProcessingException | WebApplicationException e) {
  // BasicSecurityDBResourceException surfaces as an HTTP error response
  if (responseIndicatesUserAlreadyExists(e)) { /* idempotent skip */ } else throw e;
}

Prevention

When it happens

Trigger: Calling createUser (POST /druid-ext/basic-security/authentication/<authenticator>/users/<userName>) for a userName already present in the stored user map.

Common situations: 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.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/758389d6541ca3f7. Report an issue: GitHub.