apache/druid · error · IllegalStateException

Could not assign role

Error message

Could not assign role [%s] to group mapping [%s] due to concurrent update contention.

What it means

Assigning a role to an authorization group mapping failed after numRetries compare-and-swap attempts, each beaten by a concurrent writer of the group mapping/role metadata. The updater re-reads the map, re-applies the assignment, and retries with randomized delay before throwing this ISE naming the role and group mapping. It indicates metadata-storage write contention, not an invalid role or mapping.

Solutions

  1. Retry assignGroupMappingRole after a delay.
  2. Ensure only the leader coordinator writes basic-security metadata.
  3. Serialize group mapping and role provisioning workflows.
  4. Increase numRetries if concurrent updates are expected.
  5. Inspect metadata storage latency.

Example fix

// before
gms.forEach(gm -> client.assignGroupMappingRole(prefix, gm, role));
// after: retry each assignment
for (final String gm : gms) {
  await.untilAsserted(() -> client.assignGroupMappingRole(prefix, gm, role));
}
Defensive patterns

Strategy: retry

Validate before calling

// Verify group mapping and role exist first
Map<String, BasicAuthorizerGroupMapping> gms =
    BasicAuthUtils.deserializeAuthorizerGroupMappingMap(mapper, getCurrentGroupMappingMapBytes(prefix));
Map<String, BasicAuthorizerRole> roles =
    BasicAuthUtils.deserializeAuthorizerRoleMap(mapper, getCurrentRoleMapBytes(prefix));
if (gms.get(groupMappingName) == null || roles.get(roleName) == null)
  throw new IllegalArgumentException("group mapping or role missing");

Try / catch

try {
  updater.assignGroupMappingRole(prefix, groupMappingName, roleName);
} catch (IJSE e) {
  RetryUtils.retry(() -> updater.assignGroupMappingRole(prefix, groupMappingName, roleName),
                   ex -> ex instanceof IllegalStateException, MAX_ATTEMPTS);
}

Prevention

When it happens

Trigger: Calling assignGroupMappingRole while other writers repeatedly mutate authorization metadata for the same authorizer prefix, so every CAS fails through all retries.

Common situations: Automation provisioning group mappings and roles concurrently from multiple workers; simultaneous group mapping edits via the console and API; multi-writer coordinator misconfiguration.

Related errors


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

Appendix: source

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

  }

  private void assignGroupMappingRoleInternal(String prefix, String groupMappingName, String roleName)
  {
    int attempts = 0;
    while (attempts < numRetries) {
      if (assignGroupMappingRoleOnce(prefix, groupMappingName, roleName)) {
        return;
      } else {
        attempts++;
      }
      try {
        Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY));
      }
      catch (InterruptedException ie) {
        throw new RuntimeException(ie);
      }
    }
    throw new ISE("Could not assign role [%s] to group mapping [%s] due to concurrent update contention.",
                  roleName,
                  groupMappingName
    );
  }

  private void unassignGroupMappingRoleInternal(String prefix, String groupMappingName, String roleName)
  {
    int attempts = 0;
    while (attempts < numRetries) {
      if (unassignGroupMappingRoleOnce(prefix, groupMappingName, roleName)) {
        return;
      } else {
        attempts++;
      }
      try {
        Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY));
      }
      catch (InterruptedException ie) {

View on GitHub (pinned to 9b90983fd2)