{"record":{"id":"74a72728e7a19985","repo":"apache/cassandra","slug":"s-already-exists-74a727","errorCode":null,"errorMessage":"%s already exists","messagePattern":"(.+?) already exists","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/CreateRoleStatement.java","lineNumber":97,"sourceCode":"        opts.validate();\n        if (role.getRoleName().isEmpty())\n            throw new InvalidRequestException(\"Role name can't be an empty string\");\n\n        if (dcPermissions != null)\n        {\n            dcPermissions.validate();\n        }\n\n        if (cidrPermissions != null)\n        {\n            cidrPermissions.validate();\n        }\n\n        // validate login here before authorize to avoid leaking role existence to anonymous users.\n        state.ensureNotAnonymous();\n\n        if (!ifNotExists && role != RoleResource.GENERATED_ROLE && DatabaseDescriptor.getRoleManager().isExistingRole(role))\n            throw new InvalidRequestException(String.format(\"%s already exists\", role.getRoleName()));\n    }\n\n    public ResultMessage execute(ClientState state) throws RequestExecutionException, RequestValidationException\n    {\n        // not rejected in validate()\n        if (ifNotExists && role != RoleResource.GENERATED_ROLE && DatabaseDescriptor.getRoleManager().isExistingRole(role))\n            return null;\n\n        RoleResource roleResource;\n        if (opts.isGeneratedName())\n        {\n            Map<String, Object> options = (Map<String, Object>) opts.getOptions().get(IRoleManager.Option.OPTIONS);\n            String generatedName = Guardrails.roleNamePolicy.generate(state, options);\n            if (generatedName != null)\n                roleResource = RoleResource.role(generatedName);\n            else\n                throw new InvalidRequestException(\"You have to enable role_name_policy and its generator_class_name property \" +\n                                                  \"in cassandra.yaml to be able to generate role names.\");","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/CreateRoleStatement.java#L79-L115","documentation":"CreateRoleStatement.validate checks the role manager for an existing role and throws InvalidRequestException when the role already exists and IF NOT EXISTS was not specified. This pre-validation happens after ensureNotAnonymous so anonymous users cannot probe for role existence.","triggerScenarios":"Executing CREATE ROLE existing_name (without IF NOT EXISTS) when DatabaseDescriptor.getRoleManager().isExistingRole(role) returns true and the role is not the generated role.","commonSituations":"Idempotent provisioning scripts re-run against a cluster where the role was already created; concurrent setup jobs both creating the same role; CI reusing a persistent test cluster.","solutions":["Use CREATE ROLE IF NOT EXISTS <name> ... to make the statement idempotent.","Check existence first via LIST ROLES or a role-management tool before creating.","Handle the existing role as a success case in provisioning scripts."],"exampleFix":"// before\nCREATE ROLE service_a WITH LOGIN = true AND PASSWORD = 'x';\n// after\nCREATE ROLE IF NOT EXISTS service_a WITH LOGIN = true AND PASSWORD = 'x';","handlingStrategy":"validation","validationCode":"// make idempotent at the CQL level\nconst stmt = `CREATE ROLE IF NOT EXISTS ${name} WITH LOGIN = true`;","typeGuard":null,"tryCatchPattern":"try { session.execute(cql); } catch (InvalidRequestException e) { if (e.getMessage().endsWith(\"already exists\")) { /* treat as success for idempotent provisioning */ } else throw e; }","preventionTips":["Always use IF NOT EXISTS in provisioning/CI scripts","Treat 'already exists' as a success case in idempotent automation","Serialize role-creation steps to avoid concurrent duplicate creates"],"tags":["cql","roles","duplicate-entity"],"backgroundTag":"file-already-exists","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}