apache/druid · error · RuntimeException
Couldn't deserialize authenticator userMap!
Error message
Couldn't deserialize authenticator userMap!
What it means
BasicAuthUtils.deserializeAuthenticatorUserMap turns stored bytes into the authenticator user map via Jackson. If the bytes are not valid JSON or don't match Map<String, BasicAuthenticatorUser>, it wraps the IOException in a RuntimeException('Couldn't deserialize authenticator userMap!'). The stored user-map blob is corrupt or written by an incompatible version.
Source
Thrown at extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicAuthUtils.java:134
catch (IllegalArgumentException iae) {
return null;
}
}
public static Map<String, BasicAuthenticatorUser> deserializeAuthenticatorUserMap(
ObjectMapper objectMapper,
byte[] userMapBytes
)
{
Map<String, BasicAuthenticatorUser> userMap;
if (userMapBytes == null) {
userMap = new HashMap<>();
} else {
try {
userMap = objectMapper.readValue(userMapBytes, AUTHENTICATOR_USER_MAP_TYPE_REFERENCE);
}
catch (IOException ioe) {
throw new RuntimeException("Couldn't deserialize authenticator userMap!", ioe);
}
}
return userMap;
}
public static byte[] serializeAuthenticatorUserMap(
ObjectMapper objectMapper,
Map<String, BasicAuthenticatorUser> userMap
)
{
try {
return objectMapper.writeValueAsBytes(userMap);
}
catch (IOException ioe) {
throw new ISE(ioe, "Couldn't serialize authenticator userMap!");
}
}
View on GitHub (pinned to 9b90983fd2)
Solutions
- Inspect and repair/replace the userMap record in metadata storage (re-save users via the security API to rewrite valid JSON)
- Confirm the Druid/basic-security version is uniform across the cluster; serialize again after upgrade
- Restore the record from a backup and avoid manual edits to the JSON blob
Example fix
// before
// hand-edited row in metadata store: {"users": ...} wrong shape
// after
curl -X POST http://coordinator:8084/druid-ext/basic-security/authentication/db/auth_users/users/alice -H'Content-Type: application/json' -d '{"identity":"alice","credentials":{...}}' Defensive patterns
Strategy: try-catch
Validate before calling
// Validate bytes parse as JSON before deserializing
if (bytes != null && bytes.length > 0) {
mapper.readTree(bytes); // throws if corrupt
} Try / catch
try {
Map<String, BasicAuthenticatorUser> users = BasicAuthUtils.deserializeAuthenticatorUserMap(mapper, bytes);
} catch (RuntimeException e) {
if (e.getMessage().contains("Couldn't deserialize authenticator userMap!")) {
users = new HashMap<>(); // or restore from backup
} else throw e;
} Prevention
- Never hand-edit userMap rows in metadata storage
- Re-save users via the security API after upgrades
- Back up metadata before rolling upgrades
- Keep basic-security versions uniform cluster-wide
When it happens
Trigger: Reading the authenticator userMap from metadata storage / coordinator endpoints when the byte[] is corrupt, empty-but-nonnull garbage, or was serialized with a different class schema.
Common situations: Manually edited metadata-store records, failed partial writes, rolling upgrades/downgrades changing BasicAuthenticatorUser serialization, or cross-copying user maps between authenticator types.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Couldn't serialize authenticator userMap!
- Couldn't deserialize authorizer userMap!
- Couldn't serialize authorizer userMap!
- Couldn't deserialize authorizer groupMappingMap!
- Couldn't serialize authorizer groupMappingMap!
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/42e9a7716f7171f7.
Report an issue: GitHub.