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

  1. Ensure the key class extends ExtensionKey so extract reads it from cm.extensions.
  2. If the key should be core metadata, register its resolver in the CORE_METADATA map in MetadataKeys.
  3. Check for version skew: a key defined in a newer/older build may be unrecognized; align versions.
  4. 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

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


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)