{"record":{"id":"42e9a7716f7171f7","repo":"apache/druid","slug":"couldn-t-deserialize-authenticator-usermap","errorCode":null,"errorMessage":"Couldn't deserialize authenticator userMap!","messagePattern":"Couldn't deserialize authenticator userMap!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicAuthUtils.java","lineNumber":134,"sourceCode":"    catch (IllegalArgumentException iae) {\n      return null;\n    }\n  }\n\n  public static Map<String, BasicAuthenticatorUser> deserializeAuthenticatorUserMap(\n      ObjectMapper objectMapper,\n      byte[] userMapBytes\n  )\n  {\n    Map<String, BasicAuthenticatorUser> userMap;\n    if (userMapBytes == null) {\n      userMap = new HashMap<>();\n    } else {\n      try {\n        userMap = objectMapper.readValue(userMapBytes, AUTHENTICATOR_USER_MAP_TYPE_REFERENCE);\n      }\n      catch (IOException ioe) {\n        throw new RuntimeException(\"Couldn't deserialize authenticator userMap!\", ioe);\n      }\n    }\n    return userMap;\n  }\n\n  public static byte[] serializeAuthenticatorUserMap(\n      ObjectMapper objectMapper,\n      Map<String, BasicAuthenticatorUser> userMap\n  )\n  {\n    try {\n      return objectMapper.writeValueAsBytes(userMap);\n    }\n    catch (IOException ioe) {\n      throw new ISE(ioe, \"Couldn't serialize authenticator userMap!\");\n    }\n  }\n","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/BasicAuthUtils.java#L116-L152","documentation":"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.","triggerScenarios":"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.","commonSituations":"Manually edited metadata-store records, failed partial writes, rolling upgrades/downgrades changing BasicAuthenticatorUser serialization, or cross-copying user maps between authenticator types.","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"],"exampleFix":"// before\n// hand-edited row in metadata store: {\"users\": ...} wrong shape\n// after\ncurl -X POST http://coordinator:8084/druid-ext/basic-security/authentication/db/auth_users/users/alice -H'Content-Type: application/json' -d '{\"identity\":\"alice\",\"credentials\":{...}}'","handlingStrategy":"try-catch","validationCode":"// Validate bytes parse as JSON before deserializing\nif (bytes != null && bytes.length > 0) {\n  mapper.readTree(bytes); // throws if corrupt\n}","typeGuard":null,"tryCatchPattern":"try {\n  Map<String, BasicAuthenticatorUser> users = BasicAuthUtils.deserializeAuthenticatorUserMap(mapper, bytes);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"Couldn't deserialize authenticator userMap!\")) {\n    users = new HashMap<>(); // or restore from backup\n  } else throw e;\n}","preventionTips":["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"],"tags":["java","security","jackson","serialization"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}