apache/cassandra · error · InvalidRequestException
Invalid value for property '%s'. It must be a string
Error message
Invalid value for property '%s'. It must be a string
What it means
RoleOptions.validate() requires the PASSWORD option value to be a String. If the CQL term for PASSWORD parses to another type (e.g. a number or boolean literal), validate() throws InvalidRequestException stating the property must be a string.
Source
Thrown at src/java/org/apache/cassandra/auth/RoleOptions.java:154
{
for (Map.Entry<IRoleManager.Option, Object> option : options.entrySet())
{
if (!DatabaseDescriptor.getRoleManager().supportedOptions().contains(option.getKey()))
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());
}View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Quote the password: WITH PASSWORD = '12345'.
- In programmatic construction, put a String value into the options map for IRoleManager.Option.PASSWORD.
- Escape special characters in passwords per CQL string literal rules.
Example fix
// before CREATE ROLE alice WITH PASSWORD = 12345; // after CREATE ROLE alice WITH PASSWORD = '12345';
Defensive patterns
Strategy: type-guard
Validate before calling
Object v = roleOptions.get(IRoleManager.Option.PASSWORD);
if (v != null && !(v instanceof String))
throw new IllegalArgumentException("PASSWORD must be a quoted CQL string"); Type guard
boolean isStringOption(Object v) { return v instanceof String; } Try / catch
try {
session.execute("CREATE ROLE alice WITH PASSWORD = ?", password); // driver sends String
} catch (InvalidRequestException e) {
if (e.getMessage().contains("It must be a string")) {
// retry with quoted string value
}
} Prevention
- Always quote passwords in CQL statements.
- Use bound parameters so types are explicit.
- Reject non-string passwords in provisioning code.
When it happens
Trigger: CREATE ROLE ... WITH PASSWORD = 12345 — the password given as an unquoted numeric literal, so it is not a String when validate() runs.
Common situations: Programmatic statement builders binding non-string values into the PASSWORD option; users writing passwords that look numeric without quotes.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Invalid value for property '%s'. It must be a boolean
- %s doesn't support %s
- Properties '%s' and '%s' are mutually exclusive
- 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/5e96e39fbb9adac8.
Report an issue: GitHub.