apache/cassandra · error · InvalidRequestException
Properties '%s' and '%s' are mutually exclusive
Error message
Properties '%s' and '%s' are mutually exclusive
What it means
A role cannot have both PASSWORD and HASHED_PASSWORD set: PASSWORD would be hashed by Cassandra while HASHED_PASSWORD supplies an already-hashed value (e.g. bcrypt). RoleOptions.validate() throws InvalidRequestException when PASSWORD is present and HASHED_PASSWORD is also in the options map.
Source
Thrown at src/java/org/apache/cassandra/auth/RoleOptions.java:158
throw new InvalidRequestException(String.format("%s doesn't support %s",
DatabaseDescriptor.getRoleManager().getClass().getName(),
option.getKey()));
switch (option.getKey())
{
case LOGIN:
case SUPERUSER:
if (!(option.getValue() instanceof Boolean))
throw new InvalidRequestException(String.format("Invalid value for property '%s'. " +
"It must be a boolean",
option.getKey()));
break;
case PASSWORD:
if (!(option.getValue() instanceof String))
throw new InvalidRequestException(String.format("Invalid value for property '%s'. " +
"It must be a string",
option.getKey()));
if (options.containsKey(IRoleManager.Option.HASHED_PASSWORD))
throw new InvalidRequestException(String.format("Properties '%s' and '%s' are mutually exclusive",
IRoleManager.Option.PASSWORD, IRoleManager.Option.HASHED_PASSWORD));
break;
case HASHED_PASSWORD:
if (!(option.getValue() instanceof String))
throw new InvalidRequestException(String.format("Invalid value for property '%s'. " +
"It must be a string",
option.getKey()));
if (options.containsKey(IRoleManager.Option.PASSWORD))
throw new InvalidRequestException(String.format("Properties '%s' and '%s' are mutually exclusive",
IRoleManager.Option.PASSWORD, IRoleManager.Option.HASHED_PASSWORD));
try
{
BCrypt.checkpw("dummy", (String) option.getValue());
}
catch (Exception e)
{
throw new InvalidRequestException("Invalid hashed password value. Please use jBcrypt.");
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Provide only PASSWORD (plaintext, hashed by the server) or only HASHED_PASSWORD (pre-hashed bcrypt), not both.
- If the password is already hashed, drop the PASSWORD option.
- Fix automation that merges both option keys into one statement.
Example fix
// before CREATE ROLE alice WITH PASSWORD = 'secret' AND HASHED_PASSWORD = '$2a$10$...'; // after CREATE ROLE alice WITH HASHED_PASSWORD = '$2a$10$...';
Defensive patterns
Strategy: validation
Validate before calling
if (roleOptions.containsKey(IRoleManager.Option.PASSWORD)
&& roleOptions.containsKey(IRoleManager.Option.HASHED_PASSWORD))
throw new IllegalArgumentException("Provide either PASSWORD or HASHED_PASSWORD, not both"); Try / catch
try {
roleOptions.validate();
} catch (InvalidRequestException e) {
if (e.getMessage().contains("mutually exclusive")) {
// drop one credential option and retry
}
} Prevention
- Decide on one credential form (plaintext or pre-hashed) per workflow.
- Validate merged option maps before issuing CREATE/ALTER ROLE.
- In migrations, strip default PASSWORD when supplying HASHED_PASSWORD.
When it happens
Trigger: CREATE ROLE/ALTER ROLE statement including both WITH PASSWORD = 'x' AND HASHED_PASSWORD = '$2a$...'.
Common situations: Migration scripts that include both plaintext and pre-hashed credentials; tools that merge default options with user-supplied options and accidentally combine both keys.
Related errors
- %s doesn't support %s
- Invalid value for property '%s'. It must be a boolean
- Invalid value for property '%s'. It must be a string
- Invalid metadata has been detected for role %s
- %s is not a valid data resource name
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/a4d46fc7f8b56e88.
Report an issue: GitHub.