apache/druid · error · BasicSecurityDBResourceException

User [%s] does not exist.

Error message

User [%s] does not exist.

What it means

Returned by the coordinator basic authorizer resource handler when a GET for a single user finds no user with that name in the authorizer's current user map. The handler catches BasicSecurityDBResourceException from the storage updater and converts it into an error HTTP response instead of returning a user payload.

Source

Thrown at extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/endpoint/CoordinatorBasicAuthorizerResourceHandler.java:466

  {
    return Response.status(Response.Status.BAD_REQUEST)
                   .entity(ImmutableMap.<String, Object>of(
                       "error", bsre.getMessage()
                   ))
                   .build();
  }

  private Response getUserSimple(String authorizerName, String userName)
  {
    Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap(
        objectMapper,
        storageUpdater.getCurrentUserMapBytes(authorizerName)
    );

    try {
      BasicAuthorizerUser user = userMap.get(userName);
      if (user == null) {
        throw new BasicSecurityDBResourceException("User [%s] does not exist.", userName);
      }
      return Response.ok(user).build();
    }
    catch (BasicSecurityDBResourceException e) {
      return makeResponseForBasicSecurityDBResourceException(e);
    }
  }

  private Response getUserFull(String authorizerName, String userName, boolean simplifyPermissions)
  {
    Map<String, BasicAuthorizerUser> userMap = BasicAuthUtils.deserializeAuthorizerUserMap(
        objectMapper,
        storageUpdater.getCurrentUserMapBytes(authorizerName)
    );

    try {
      BasicAuthorizerUser user = userMap.get(userName);
      if (user == null) {

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. List users first (GET .../users) and confirm the exact name before fetching one
  2. Create the user via POST .../users/<userName> if it should exist
  3. Check authorizerName in the request/config (e.g. 'internal' vs a custom authenticator's authorizer)
  4. Handle the 400/404 response in callers instead of assuming the user exists

Example fix

// before
BasicAuthorizerUser u = client.getUser("internal-auth", "Alice");
// after (names are case-sensitive; verify existence)
List<BasicAuthorizerUser> users = client.getUsers("internal-auth");
if (users.stream().anyMatch(x -> x.getName().equals("alice"))) {
  BasicAuthorizerUser u = client.getUser("internal-auth", "alice");
}
Defensive patterns

Strategy: try-catch

Validate before calling

// verify user exists before fetching
boolean exists = listUsers(authorizer).stream()
    .anyMatch(u -> u.getName().equals(userName));
if (!exists) return null;

Type guard

boolean userExists(List<BasicAuthorizerUser> users, String name) {
  return users != null && name != null && users.stream().anyMatch(u -> name.equals(u.getName()));
}

Try / catch

try {
  return getUser(authorizer, userName);
} catch (BasicSecurityDBResourceException e) {
  if (e.getMessage().contains("does not exist")) return null; // caller decides
  throw e;
}

Prevention

When it happens

Trigger: GET /druid-ext/basic-security/authorization/db/v1/<authorizerName>/users/<userName> with a username that was never created or was deleted; typo in userName; querying the wrong authorizerName; user removed by another admin between listing and fetching.

Common situations: Scripts that iterate over remembered usernames after the users were deleted; case-sensitivity mistakes (Druid usernames are case-sensitive); pointing integration tooling at a fresh metadata store with no users; misconfigured authorizerName in client config.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


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