apache/druid · error · RuntimeException
Couldn't deserialize authorizer roleMap!
Error message
Couldn't deserialize authorizer roleMap!
What it means
Thrown by BasicAuthUtils.deserializeAuthorizerRoleMap when Jackson cannot read the stored byte array back into a Map<String, BasicAuthorizerRole>. Druid persists role maps as serialized JSON in metadata storage; if those bytes are unreadable or not valid JSON of the expected shape, deserialization fails and this RuntimeException is thrown. It usually means corrupted or malformed persisted data.
Source
Thrown at extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicAuthUtils.java:224
catch (IOException ioe) {
throw new ISE(ioe, "Couldn't serialize authorizer groupMappingMap!");
}
}
public static Map<String, BasicAuthorizerRole> deserializeAuthorizerRoleMap(
ObjectMapper objectMapper,
byte[] roleMapBytes
)
{
Map<String, BasicAuthorizerRole> roleMap;
if (roleMapBytes == null) {
roleMap = new HashMap<>();
} else {
try {
roleMap = objectMapper.readValue(roleMapBytes, BasicAuthUtils.AUTHORIZER_ROLE_MAP_TYPE_REFERENCE);
}
catch (IOException ioe) {
throw new RuntimeException("Couldn't deserialize authorizer roleMap!", ioe);
}
}
return roleMap;
}
public static byte[] serializeAuthorizerRoleMap(ObjectMapper objectMapper, Map<String, BasicAuthorizerRole> roleMap)
{
try {
return objectMapper.writeValueAsBytes(roleMap);
}
catch (IOException ioe) {
throw new ISE(ioe, "Couldn't serialize authorizer roleMap!");
}
}
public static void maybeInitialize(final RetryUtils.Task<?> task)
{
try {View on GitHub (pinned to 9b90983fd2)
Solutions
- Log/inspect the raw roleMapBytes and the wrapped IOException to identify the parse failure point
- Verify the metadata-store record for the role map is complete valid JSON matching BasicAuthorizerRole
- Check whether a version upgrade changed the persisted format and re-run any required migration/upgrade scripts
- Restore the role map from a good metadata store backup and re-create roles via the API
Defensive patterns
Strategy: try-catch
Validate before calling
boolean looksLikeRoleMap(byte[] b) { return b != null && b.length > 0 && b[0] == '{'; } Type guard
boolean isValidRoleMapBytes(byte[] bytes) { try (JsonParser p = jsonMapper.getFactory().createParser(bytes)) { while (p.nextToken() != null) {} return true; } catch (IOException e) { return false; } } Try / catch
try { Map<String, BasicAuthorizerRole> roles = BasicAuthUtils.deserializeAuthorizerRoleMap(jsonMapper, bytes); } catch (RuntimeException e) { LOG.error(e, "corrupt roleMap bytes; restoring from backup"); roles = restoreFromBackupOrDefault(); } Prevention
- Validate stored bytes are complete JSON before deserializing after upgrades
- Back up metadata-store tables (druid_basic_roles) before version upgrades
- Never hand-edit serialized role-map rows in the database
- Confirm all nodes run the same Druid basic-security version
When it happens
Trigger: Reading roleMapBytes from metadata storage that were written by an incompatible version, truncated, corrupted, or are not JSON matching BasicAuthorizerRole's expected shape (including empty bytes that are non-null and non-empty but invalid).
Common situations: Upgrading Druid across schema-incompatible basic-security versions; manual edits to the druid_basic_roles metadata table; interrupted writes leaving partial JSON in the DB.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Failed to deserialize DiscoveryDruidNode[%s]
- Invalid JSON inside unknown key:
- Unknown TableState code:
- unknown event type [%s]
- interrupted flushing elements from queue
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/15785dcde9eb5d97.
Report an issue: GitHub.