apache/cassandra · error · ConfigurationException
Token " + token + " contains non-hex digits
Error message
Token " + token + " contains non-hex digits
What it means
ByteOrderedPartitioner's token validator normalizes a hex token string (padding odd length) and then decodes it with Hex.hexToBytes; a NumberFormatException there means the string contains characters outside [0-9a-fA-F]. It is rethrown as a ConfigurationException since the token normally comes from cassandra.yaml's initial_token.
Source
Thrown at src/java/org/apache/cassandra/dht/ByteOrderedPartitioner.java:346
}
public String toString(Token token)
{
BytesToken bytesToken = (BytesToken) token;
return Hex.bytesToHex(bytesToken.token);
}
public void validate(String token) throws ConfigurationException
{
try
{
if (token.length() % 2 == 1)
token = "0" + token;
Hex.hexToBytes(token);
}
catch (NumberFormatException e)
{
throw new ConfigurationException("Token " + token + " contains non-hex digits");
}
}
public Token fromString(String string)
{
if (string.length() % 2 == 1)
string = "0" + string;
return new BytesToken(Hex.hexToBytes(string));
}
};
public Token.TokenFactory getTokenFactory()
{
return tokenFactory;
}
@Override
public boolean accordSupported()View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Rewrite initial_token as a valid hexadecimal string (even-length, e.g. '00ffab'), matching the BOP token format.
- Remove the 0x prefix and strip whitespace before the value.
- If the token came from another partitioner, regenerate it — token formats are not interchangeable between partitioners.
- Or omit initial_token and let the node pick tokens randomly (if manual byte-order placement is not required).
Example fix
// before (cassandra.yaml) initial_token: 123456789012 # decimal, rejected // after initial_token: 0123456789012 # valid hex, padded to even length
Defensive patterns
Strategy: validation
Validate before calling
public static boolean isValidHexToken(String token) {
String t = token.trim();
if (t.startsWith("0x")) t = t.substring(2);
if (t.isEmpty() || t.length() % 2 != 0) return false;
return t.chars().allMatch(c -> Character.digit(c, 16) != -1);
} Type guard
boolean isHexString(String s) { return s != null && !s.isEmpty() && s.chars().allMatch(c -> Character.digit(c, 16) != -1); } Try / catch
try {
factory.validate(initialToken);
} catch (ConfigurationException e) {
throw new IllegalArgumentException("initial_token must be a valid even-length hex string", e);
} Prevention
- Validate initial_token in CI/config linting before deploying cassandra.yaml.
- Never copy tokens between clusters with different partitioners.
- Strip 0x prefixes and whitespace from token strings.
When it happens
Trigger: Setting initial_token to a non-hex string (e.g. decimal number, '0x...' prefix, whitespace or stray characters) with ByteOrderedPartitioner; calling TokenFactory.validate(token) programmatically with a malformed string.
Common situations: Copy-pasting a token from decimal notation used by RandomPartitioner/Murmur3Partitioner into a BOP cluster; hand-editing cassandra.yaml; '0x' prefix that Hex does not accept.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Token must be >= 0 and <= 2**127
- Invalid data rate: value must be non-negative
- Invalid data storage: %s Accepted units:%s
- Invalid value of entire_sstable_stream_throughput_outbound:
- Invalid value of entire_sstable_inter_dc_stream_throughput_o
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/88ae104c642970d6.
Report an issue: GitHub.