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

  1. Remove the password key and keep only password_hash (preferred, avoids plaintext in yaml)
  2. Or remove password_hash and keep only password
  3. 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

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


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/2164760617235756. Report an issue: GitHub.