{"record":{"id":"605519d4bb24c6a3","repo":"apache/druid","slug":"could-not-delete-user-s-due-to-concurrent-updat","errorCode":null,"errorMessage":"Could not delete user [%s] due to concurrent update contention.","messagePattern":"Could not delete user \\[(.+?)\\] due to concurrent update contention\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":500,"severity":"error","filePath":"extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/db/updater/CoordinatorBasicAuthorizerMetadataStorageUpdater.java","lineNumber":688,"sourceCode":"  }\n\n  private void deleteUserInternal(String prefix, String userName)\n  {\n    int attempts = 0;\n    while (attempts < numRetries) {\n      if (deleteUserOnce(prefix, userName)) {\n        return;\n      } else {\n        attempts++;\n      }\n      try {\n        Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY));\n      }\n      catch (InterruptedException ie) {\n        throw new RuntimeException(ie);\n      }\n    }\n    throw new ISE(\"Could not delete user [%s] due to concurrent update contention.\", userName);\n  }\n\n  private void createGroupMappingInternal(String prefix, BasicAuthorizerGroupMapping groupMapping)\n  {\n    int attempts = 0;\n    while (attempts < numRetries) {\n      if (createGroupMappingOnce(prefix, groupMapping)) {\n        return;\n      } else {\n        attempts++;\n      }\n      try {\n        Thread.sleep(ThreadLocalRandom.current().nextLong(UPDATE_RETRY_DELAY));\n      }\n      catch (InterruptedException ie) {\n        throw new RuntimeException(ie);\n      }\n    }","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-basic-security/src/main/java/org/apache/druid/security/basic/authorization/db/updater/CoordinatorBasicAuthorizerMetadataStorageUpdater.java#L670-L706","documentation":"Thrown as IllegalStateException when deleteUserInternal fails to delete an authorizer user after exhausting all compare-and-swap retries. Persistent concurrent modification of the authorizer user map prevented the deletion from committing. Similar family to the authenticator-side contention errors.","triggerScenarios":"Calling deleteUser on the authorizer storage updater while other writers keep changing the same authorizer user map, so every tryUpdateUserMap attempt fails across all retries.","commonSituations":"Concurrent admin operations or scripts deleting/modifying authorizer users; multiple coordinators acting as writers; metadata store slowdowns causing CAS retries to time out; retry storms during cluster upgrades.","solutions":["Ensure only the elected coordinator writes (check leadership and any manually-triggered update endpoints)","Retry the deletion after backoff once concurrent updates settle","Check metadata store performance and health","Raise numRetries/UPDATE_RETRY_DELAY if contention is chronic in your deployment"],"exampleFix":"// before\nclient.deleteAuthorizerUser(authorizerName, userName); // ISE under contention\n// after\ntry {\n  client.deleteAuthorizerUser(authorizerName, userName);\n} catch (IllegalStateException e) {\n  Thread.sleep(retryBackoffMs);\n  client.deleteAuthorizerUser(authorizerName, userName);\n}","handlingStrategy":"retry","validationCode":"// confirm the user exists before deleting\nResponse r = client.getAuthorizerUser(authorizerName, userName);\nif (r.getStatus() != 200) { return; }","typeGuard":null,"tryCatchPattern":"try {\n  client.deleteAuthorizerUser(authorizerName, userName);\n} catch (IllegalStateException e) {\n  backoffAndRetry(() -> client.deleteAuthorizerUser(authorizerName, userName));\n}","preventionTips":["Serialize authorizer user-management operations across tools","Verify single-coordinator leadership","Monitor and fix metadata store latency issues that prolong contention"],"tags":["concurrency","optimistic-locking","authorization","basic-security"],"backgroundTag":"internal-invariant-violation","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}