elastic/elasticsearch · error · IllegalArgumentException
CEF extensions contain unescaped equals sign
Error message
CEF extensions contain unescaped equals sign
What it means
Thrown by CefParser.parseExtensions when the first chunk's key — i.e. the text before the first '=' — is empty or contains whitespace. A whitespace-containing key indicates an unescaped '=' was missing earlier, so the parser ended up treating prose as a key. The constant UNESCAPED_EQUALS_SIGN is reused here even though the actual root cause can also be an empty leading key.
Source
Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/CefParser.java:421
}
chunks.add(buffer.toString()); // don't forget the ragged-edge last chunk ;)
if (chunks.size() == 1) {
String chunk = chunks.getFirst();
if (chunk.isEmpty()) {
return Map.of();
} else {
throw new IllegalArgumentException("Invalid extensions in the CEF event: " + chunk);
}
}
// now turn chunks into pairs by splitting on the last space character
// given 'foo', 'bar\bar = bar baz ', 'quux ', we want to end up with { 'foo': 'bar\bar = bar ', 'baz': 'quux'}
Map<String, String> extensions = HashMap.newHashMap(chunks.size() - 1);
String key, value, chunk;
key = chunks.getFirst();
if (key.isEmpty() || containsWhitespace(key)) {
throw new IllegalArgumentException(UNESCAPED_EQUALS_SIGN); // TODO I'm not sure this error message is actually fair anymore
}
for (int j = 1; j < chunks.size() - 1; j++) {
chunk = chunks.get(j);
int idx = chunk.lastIndexOf(' ');
if (idx == -1) {
value = "";
} else {
value = chunk.substring(0, idx);
}
if (ignoreEmptyValues == false || Strings.isEmpty(value) == false) {
extensions.put(key, value);
}
key = chunk.substring(idx + 1);
if (key.isEmpty() || containsWhitespace(key)) {
throw new IllegalArgumentException(UNESCAPED_EQUALS_SIGN); // TODO I'm not sure this error message is actually fair anymore
}
}View on GitHub (pinned to db6a809a66)
Solutions
- Inspect the raw CEF extension block — confirm it starts with a bare key (no spaces) followed immediately by '='.
- Strip any leading prose or whitespace-only prefix before invoking the cef processor.
- Use an on_failure pipeline to quarantine malformed events.
- If the producer is yours, emit only 'key=value' pairs in the extension section per the CEF spec.
Example fix
// before — leading text before the first '=' reads as a whitespace-containing key // field: 'CEF:0|v|p|1.0|1|n|3|some free text act=login next=...' // // after — extension section begins with a clean key=value pair // field: 'CEF:0|v|p|1.0|1|n|3|act=login next=...'
Defensive patterns
Strategy: validation
Validate before calling
// The first extension key must be non-empty and contain no whitespace.
boolean firstKeyLooksValid(String ext) {
if (ext == null) return true;
int eq = ext.indexOf('=');
if (eq < 0) return false;
String key = ext.substring(0, eq);
return !key.isEmpty() && key.chars().noneMatch(Character::isWhitespace);
} Try / catch
{
"on_failure": [
{ "set": { "field": "ingest.error", "value": "cef-bad-first-key" } },
{ "redirect": { "pipeline": "quarantine" } }
]
} Prevention
- Inspect the segment immediately before the first '=' — it must be a bare key with no spaces.
- Trim leading prose from CEF extension sections upstream.
- Use on_failure to capture the offending value for producer-side fixes.
When it happens
Trigger: Extension string that begins with '=' (empty first key), or that contains words and spaces before the first '='. Examples: '=value second=...', 'foo bar baz=key second=...' (the leading 'foo bar baz' segment, after splitting on '=', leaves a key with internal whitespace).
Common situations: Producer emits a stray '=' at the start of the extension block; a leading free-text fragment precedes the real extensions; field extraction upstream concatenated non-extension text with the extension section.
Related errors
- Invalid extensions in the CEF event: {}
- Illegal escape sequence '\{}'
- Value is not a valid timestamp: {}
- unable to parse URI [${uriString}]
- Invalid CEF format
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/be0fbddeece1c45b.
Report an issue: GitHub.