apache/druid · error · BasicSecurityDBResourceException

Group mapping [%s] does not exist.

Error message

Group mapping [%s] does not exist.

What it means

BasicSecurityDBResourceException thrown by deleteGroupMappingOnce when the named group mapping is not found in the authorizer's group-mapping map. Deletion is only valid for existing entities; the coordinator validates presence before writing the updated map. Indicates a stale reference or wrong authorizer prefix rather than an internal failure.

Source

Thrown at extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/db/updater/CoordinatorBasicAuthorizerMetadataStorageUpdater.java:898

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

  private boolean deleteGroupMappingOnce(String prefix, String groupMappingName)
  {
    byte[] oldValue = getCurrentGroupMappingMapBytes(prefix);
    Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap(objectMapper, oldValue);
    if (groupMappingMap.get(groupMappingName) == null) {
      throw new BasicSecurityDBResourceException("Group mapping [%s] does not exist.", groupMappingName);
    } else {
      groupMappingMap.remove(groupMappingName);
    }
    byte[] newValue = BasicAuthUtils.serializeAuthorizerGroupMappingMap(objectMapper, groupMappingMap);
    return tryUpdateGroupMappingMap(prefix, groupMappingMap, oldValue, newValue);
  }

  private boolean createGroupMappingOnce(String prefix, BasicAuthorizerGroupMapping groupMapping)
  {
    byte[] oldValue = getCurrentGroupMappingMapBytes(prefix);
    Map<String, BasicAuthorizerGroupMapping> groupMappingMap = BasicAuthUtils.deserializeAuthorizerGroupMappingMap(objectMapper, oldValue);
    if (groupMappingMap.get(groupMapping.getName()) != null) {
      throw new BasicSecurityDBResourceException("Group mapping [%s] already exists.", groupMapping.getName());
    } else {
      groupMappingMap.put(groupMapping.getName(), groupMapping);
    }
    byte[] newValue = BasicAuthUtils.serializeAuthorizerGroupMappingMap(objectMapper, groupMappingMap);
    return tryUpdateGroupMappingMap(prefix, groupMappingMap, oldValue, newValue);

View on GitHub (pinned to 9b90983fd2)

Solutions

  1. List existing mappings with GET /druid-ext/basic-security/authorization/db/<authorizer>/groupMappings to confirm the exact name
  2. Make deletes idempotent: ignore 'does not exist' responses in cleanup scripts
  3. Check you are using the correct authorizer name in the URL path
  4. Recreate the mapping if the delete was premature

Example fix

// before
deleteGroupMapping("default", "ldapAdmins");
// after
if (groupMappingExists("default", "ldapAdmins")) {
  deleteGroupMapping("default", "ldapAdmins");
}
Defensive patterns

Strategy: validation

Validate before calling

boolean exists = getGroupMappings(authorizer).stream()
    .anyMatch(gm -> gm.equals(groupMappingName));
if (!exists) log.warn("Skipping delete, mapping absent: " + groupMappingName);

Try / catch

try {
  client.deleteGroupMapping("default", name);
} catch (BasicSecurityDBResourceException e) {
  if (e.getMessage().contains("does not exist")) {
    log.info("Group mapping {} already gone", name);
  } else { throw e; }
}

Prevention

When it happens

Trigger: DELETE /druid-ext/basic-security/authorization/db/<authorizer>/groupMappings/<groupMappingName> for a mapping that does not exist in that authorizer.

Common situations: The mapping was already deleted (double delete in a script); typo in the mapping name; delete issued against the wrong authorizer; LdapGroupMapping config renamed between versions.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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