apache/cassandra · error · ConfigurationException
Only one of %s, %s can be specified.
Error message
Only one of %s, %s can be specified.
What it means
The default role may be seeded from exactly one secret source. validateConfiguration() rejects configurations that specify both plaintext password and password_hash, since they are mutually exclusive and ambiguous (which one is authoritative?).
Source
Thrown at src/java/org/apache/cassandra/auth/PasswordDefaultRoleInitializer.java:118
@Override
public String defaultRoleName()
{
return role;
}
@Override
public void validateConfiguration() throws ConfigurationException
{
if (Strings.isNullOrEmpty(role))
throw new ConfigurationException(String.format("%s requires a non-empty %s parameter", getClass().getSimpleName(), ROLE));
boolean specifiedPassword = !Strings.isNullOrEmpty(password);
boolean specifiedPasswordHash = !Strings.isNullOrEmpty(passwordHash);
if (!specifiedPassword && !specifiedPasswordHash)
throw new ConfigurationException(String.format("There has to be one of %s, %s specified.", PASSWORD, PASSWORD_HASH));
else if (specifiedPassword && specifiedPasswordHash)
throw new ConfigurationException(String.format("Only one of %s, %s can be specified.", PASSWORD, PASSWORD_HASH));
}
@VisibleForTesting
public String createDefaultRoleQuery()
{
return String.format("INSERT INTO %s.%s (role, is_superuser, can_login, salted_hash) VALUES ('%s', true, true, '%s') USING TIMESTAMP 0",
SchemaConstants.AUTH_KEYSPACE_NAME,
AuthKeyspace.ROLES,
escapeCqlLiteral(role),
escapeCqlLiteral(password == null ? passwordHash : hashpw(password)));
}
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Remove the password key and keep only password_hash (preferred, avoids plaintext in yaml)
- Or remove password_hash and keep only password
- Keep a single canonical source for the secret in your config management to avoid re-introducing the conflict
Example fix
// before role_name: cassandra password: ChangeMeNow password_hash: $2a$10$... // after role_name: cassandra password_hash: $2a$10$...
Defensive patterns
Strategy: validation
Validate before calling
if (notBlank(password) && notBlank(passwordHash)) fail("password and password_hash are mutually exclusive"); Type guard
boolean exactlyOneSecret(Map<String,String> o) { int n = (notBlank(o.get("password"))?1:0) + (notBlank(o.get("password_hash"))?1:0); return n == 1; } Try / catch
try { config.validate(); } catch (ConfigurationException e) { if (e.getMessage().startsWith("Only one of")) dropPlaintextField(); } Prevention
- Model the two fields as a single choice (oneOf) in config tooling
- When migrating to password_hash, delete the password key in the same change
- Add a lint rule for cassandra.yaml rejecting both keys together
When it happens
Trigger: cassandra.yaml default role options containing both password and password_hash keys with non-empty values.
Common situations: Merging yaml fragments where one file sets password and another sets password_hash; migrating from plaintext to hashed secrets without deleting the old key; automation templates writing both fields.
Related errors
- %s has authorization enabled which requires %s to enable aut
- %s requires %s
- %s can't be used with %s
- %s does not support %s
- Failed to instantiate %s
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/2164760617235756.
Report an issue: GitHub.