apache/cassandra · error · IllegalArgumentException
Unknown key:
Error message
Unknown key:
What it means
MetadataKeys.extract resolves a MetadataKey against a ClusterMetadata snapshot. Keys in the CORE_METADATA map are looked up directly; anything else must be an ExtensionKey whose value lives in cm.extensions. If a non-core, non-extension key is passed, extract throws IllegalArgumentException("Unknown key: " + key), indicating the caller supplied a key type the resolver cannot handle.
Solutions
- Ensure the key class extends ExtensionKey so extract reads it from cm.extensions.
- If the key should be core metadata, register its resolver in the CORE_METADATA map in MetadataKeys.
- Check for version skew: a key defined in a newer/older build may be unrecognized; align versions.
- Validate key type before calling extract (see validation code) to fail fast with a clearer message.
Example fix
// before
MetadataValue<?> v = MetadataKeys.extract(cm, myKey);
// after
if (!(myKey instanceof ExtensionKey) && !MetadataKeys.isCoreKey(myKey)) // add isCoreKey or instanceof check first
throw new IllegalArgumentException("Key must be core or an ExtensionKey: " + myKey);
MetadataValue<?> v = MetadataKeys.extract(cm, myKey); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(key instanceof ExtensionKey) && !MetadataKeys.CORE_METADATA.containsKey(key))
throw new IllegalArgumentException("Key must be a core MetadataKey or an ExtensionKey: " + key); Type guard
boolean isResolvableKey(MetadataKey k) { return k instanceof ExtensionKey || MetadataKeys.CORE_METADATA.containsKey(k); } Try / catch
try { v = MetadataKeys.extract(cm, key); } catch (IllegalArgumentException e) { logger.warn("Unresolvable metadata key {}", key, e); v = null; } Prevention
- Make all custom keys extend ExtensionKey
- Register new core keys in CORE_METADATA
- Keep key definitions in sync across versions in a cluster
When it happens
Trigger: Calling MetadataKeys.extract(cm, key) where key is not registered in CORE_METADATA and is not an instance of ExtensionKey (MetadataKeys.java:81) — e.g. a custom MetadataKey implementation, or a key from a different/older version not present in CORE_METADATA.
Common situations: Tooling or tests enumerating metadata keys with a hand-rolled MetadataKey; version skew where a plugin's key class isn't an ExtensionKey subclass; refactor renamed key classes so they no longer extend ExtensionKey.
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
- Cannot run accord only repair on
- Cannot run paxos only repair on
- denylist_max_keys_per_table must be a positive integer.
- denylist_max_keys_total must be a positive integer.
- Maximum number of workers must not be negative
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/5281d5ebad893b95.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/tcm/MetadataKeys.java:81
public static MetadataKey make(String...parts)
{
assert parts != null && parts.length >= 1;
StringBuilder b = new StringBuilder(parts[0]);
for (int i = 1; i < parts.length; i++)
{
b.append('.');
b.append(parts[i]);
}
return new MetadataKey(b.toString());
}
public static MetadataValue<?> extract(ClusterMetadata cm, MetadataKey key)
{
if (CORE_METADATA.containsKey(key))
return CORE_METADATA.get(key).apply(cm);
if (!(key instanceof ExtensionKey<?, ?>))
throw new IllegalArgumentException("Unknown key: " + key);
return cm.extensions.get(key);
}
public static ImmutableSet<MetadataKey> diffKeys(ClusterMetadata before, ClusterMetadata after)
{
ImmutableSet.Builder<MetadataKey> builder = new ImmutableSet.Builder<>();
diffKeys(before, after, builder);
return builder.build();
}
private static void diffKeys(ClusterMetadata before, ClusterMetadata after, ImmutableSet.Builder<MetadataKey> builder)
{
for (Map.Entry<MetadataKey, Function<ClusterMetadata, MetadataValue<?>>> e : CORE_METADATA.entrySet())
checkKey(before, after, builder, e.getValue(), e.getKey());
Set<ExtensionKey<?,?>> added = new HashSet<>(after.extensions.keySet());
for (Map.Entry<ExtensionKey<?, ?>, ExtensionValue<?>> entry : before.extensions.entrySet())
{View on GitHub (pinned to 88fd0f6a0e)