alibaba/Sentinel · error · IllegalArgumentException

keys empty or null

Error message

keys empty or null

What it means

The array-based StatEntry constructor throws IllegalArgumentException when the keys array is null or has length 0. Keys are the dimension columns of an EagleEye stat row; without at least one key the row has no identity and cannot be serialized, so the constructor fails fast.

Source

Thrown at sentinel-core/src/main/java/com/alibaba/csp/sentinel/eagleeye/StatEntry.java:91

        keys[0] = key1;
        for (int i = 0; i < moreKeys.length; ++i) {
            keys[i + 1] = moreKeys[i];
        }
        this.statLogger = statLogger;
        this.keys = keys;
    }

    public StatEntry(StatLogger statLogger, List<String> keys) {
        if (keys == null || keys.isEmpty()) {
            throw new IllegalArgumentException("keys empty or null: " + keys);
        }
        this.statLogger = statLogger;
        this.keys = keys.toArray(new String[keys.size()]);
    }

    public StatEntry(StatLogger statLogger, String[] keys) {
        if (keys == null || keys.length == 0) {
            throw new IllegalArgumentException("keys empty or null");
        }
        this.statLogger = statLogger;
        this.keys = Arrays.copyOf(keys, keys.length);
    }

    public String[] getKeys() {
        return keys;
    }

    void appendTo(StringBuilder appender, char delimiter) {
        final int len = keys.length;
        if (len > 0) {
            appender.append(keys[0]);
            for (int i = 1; i < len; ++i) {
                appender.append(delimiter).append(keys[i]);
            }
        }
    }

View on GitHub (pinned to a3f40ba8e9)

Solutions

  1. Guard the array for null/length==0 before constructing StatEntry; skip or substitute a default key such as "-".
  2. Fix the upstream key derivation so an empty input cannot reach the constructor (validate the source string first).
  3. Prefer the List constructor with an explicit isEmpty check, or the fixed-key varargs form, when the key set is static.

Example fix

// before
String[] keys = rawKeys.split(",");
StatEntry e = statLogger.stat(keys); // throws when rawKeys is empty

// after
String[] keys = rawKeys.trim().isEmpty() ? new String[]{"unknown"} : rawKeys.split(",");
StatEntry e = statLogger.stat(keys);
Defensive patterns

Strategy: validation

Validate before calling

if (keys == null || keys.length == 0) {
    // skip or substitute default key
} else {
    StatEntry entry = statLogger.stat(keys);
}

Prevention

When it happens

Trigger: Calling new StatEntry(statLogger, (String[]) null) or passing a zero-length String[] — e.g. an array produced by splitting an empty string ("".split(",") yields length-1 array but trim/filter steps can collapse it) or a varargs call like statLogger.stat() with no key argument.

Common situations: Keys are derived from splitting a config/URL string that is occasionally empty. A varargs forwarding helper passes an empty array when its own varargs list is empty. Arrays.asList conversion or list.toArray on an empty collection feeds a zero-length array.

Related errors


AI-assisted analysis of alibaba/Sentinel@a3f40ba8e9 (2026-08-14). Data as JSON: /api/errors/edea669459589709. Report an issue: GitHub.