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
- Retry assignGroupMappingRole after a delay.
- Ensure only the leader coordinator writes basic-security metadata.
- Serialize group mapping and role provisioning workflows.
- Increase numRetries if concurrent updates are expected.
- 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
- Provision group mappings and roles sequentially
- Leader-only writes to metadata
- Randomized backoff between attempts
- Raise numRetries for concurrent setups
- Monitor metadata storage
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
- Could not assign role
- Could not create group mapping
- Could not create role
- Could not delete group mapping
- Could not delete role
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)