apache/druid · warning · BasicSecurityDBResourceException
User [%s] does not exist.
Error message
User [%s] does not exist.
What it means
Thrown as BasicSecurityDBResourceException when deleteUserOnce does not find the named user in the authenticator user map. Deleting a non-existent user is rejected rather than silently ignored. Surfaced to the HTTP caller as an error response.
Source
Thrown at extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authentication/db/updater/CoordinatorBasicAuthenticatorMetadataStorageUpdater.java:392
);
if (userMap.get(userName) != null) {
throw new BasicSecurityDBResourceException("User [%s] already exists.", userName);
} else {
userMap.put(userName, new BasicAuthenticatorUser(userName, null));
}
byte[] newValue = BasicAuthUtils.serializeAuthenticatorUserMap(objectMapper, userMap);
return tryUpdateUserMap(prefix, userMap, oldValue, newValue);
}
private boolean deleteUserOnce(String prefix, String userName)
{
byte[] oldValue = getCurrentUserMapBytes(prefix);
Map<String, BasicAuthenticatorUser> userMap = BasicAuthUtils.deserializeAuthenticatorUserMap(
objectMapper,
oldValue
);
if (userMap.get(userName) == null) {
throw new BasicSecurityDBResourceException("User [%s] does not exist.", userName);
} else {
userMap.remove(userName);
}
byte[] newValue = BasicAuthUtils.serializeAuthenticatorUserMap(objectMapper, userMap);
return tryUpdateUserMap(prefix, userMap, oldValue, newValue);
}
private boolean setUserCredentialOnce(String prefix, String userName, BasicAuthenticatorCredentials credentials)
{
byte[] oldValue = getCurrentUserMapBytes(prefix);
Map<String, BasicAuthenticatorUser> userMap = BasicAuthUtils.deserializeAuthenticatorUserMap(
objectMapper,
oldValue
);
if (userMap.get(userName) == null) {
throw new BasicSecurityDBResourceException("User [%s] does not exist.", userName);
} else {
userMap.put(userName, new BasicAuthenticatorUser(userName, credentials));View on GitHub (pinned to 9b90983fd2)
Solutions
- Verify the user exists via GET before calling DELETE
- Confirm the correct authenticator name is being targeted
- Make deletion idempotent in scripts: ignore 404/BasicSecurityDBResourceException responses
- Correct the userName spelling/configuration
Example fix
// before
client.deleteUser(authenticatorName, userName); // fails if missing
// after
Response res = client.deleteUser(authenticatorName, userName);
if (res.getStatus() != 200 && !"User ... does not exist".contains(userName)) {
throw new RuntimeException("delete failed");
} Defensive patterns
Strategy: validation
Validate before calling
Response r = client.getUser(authenticatorName, userName);
if (r.getStatus() != 200) { /* nothing to delete */ return; } Try / catch
try {
client.deleteUser(authenticatorName, userName);
} catch (WebApplicationException e) {
if (isDoesNotExistResponse(e)) { /* idempotent: already gone */ } else throw e;
} Prevention
- Confirm the exact userName and authenticator name before deleting
- Treat 'does not exist' deletions as success in cleanup scripts
- Check for concurrent deletions by other admins/tools
When it happens
Trigger: Calling deleteUser (DELETE /druid-ext/basic-security/authentication/<authenticator>/users/<userName>) for a userName that is not in the stored user map.
Common situations: Cleanup scripts deleting users that were already removed or never created; typo in the userName; deleting users on the wrong authenticator name (e.g. 'druid-ha' vs 'basic'); retries after a successful first delete.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- User [%s] already exists.
- User [%s] does not exist.
- User [%s] does not exist.
- Failed to stream logs from: %s
- IOException wrapping underlying cause
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/4b9f9294ce765030.
Report an issue: GitHub.