elastic/elasticsearch · error · IllegalArgumentException
Incomplete CEF header
Error message
Incomplete CEF header
What it means
IllegalArgumentException(INCOMPLETE_CEF_HEADER) from parseHeaders after the CEF prefix is confirmed valid but the pipe-splitting did not yield exactly 7 header fields. CEF defines seven mandatory header fields (Version, DeviceVendor, DeviceProduct, DeviceVersion, SignatureID, Name, Severity); missing or extra pipes both fail.
Source
Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/CefParser.java:321
i++; // and skip the next character
} else if (curr == '|') { // a pipe, it's the end of a header
headers.add(buffer.toString()); // emit the header
buffer = new StringBuilder(); // and reset the buffer
if (headers.size() == 7) {
extensionStart = i + 1; // the extensions begin after this pipe
break; // we've processed all the headers, so exit the loop
}
} else { // any other character
buffer.append(curr); // is just added to the header
}
}
if (headers.isEmpty() || headers.getFirst().startsWith("CEF:") == false) {
throw new IllegalArgumentException(INVALID_CEF_FORMAT);
}
if (headers.size() != 7) {
throw new IllegalArgumentException(INCOMPLETE_CEF_HEADER);
}
// for simplicity of the interface, pack the unparsed extension string itself into the returned list of headers
String extensionString = cefString.substring(extensionStart);
headers.add(extensionString);
return headers;
}
private static void processHeaders(List<String> headers, CefEvent event) {
for (int i = 0; i < headers.size(); i++) {
final String value = headers.get(i);
switch (i) {
case 0 -> event.addCefMapping("version", value.substring(4));
case 1 -> {
event.addCefMapping("device.vendor", value);
event.addRootMapping("observer.vendor", value);
}View on GitHub (pinned to db6a809a66)
Solutions
- Escape literal pipe characters in field values as '\|' per CEF spec
- Ensure all seven header fields are present, even if empty (emit empty fields as consecutive pipes)
- Validate the header count on the producer side before sending
Example fix
// before: only 6 fields (missing severity) -> incomplete "CEF:0|Vendor|Product|1.0|100|Name|" // after: 7 fields with severity "CEF:0|Vendor|Product|1.0|100|Name|6|ext=..."
Defensive patterns
Strategy: validation
Validate before calling
// Validate seven headers before relying on the CEF processor:
long pipes = input.chars().filter(c -> c == '|').count();
// note: unescaped pipes only; do a proper escape-aware count in production
if (pipes < 6) throw new IllegalArgumentException("Incomplete CEF header"); Try / catch
try { cefProcessor.execute(doc); }
catch (IllegalArgumentException e) {
if ("Incomplete CEF header".equals(e.getMessage())) { quarantine(doc); }
else throw e;
} Prevention
- Ensure producers emit all seven header fields, using empty values where needed
- Escape literal pipes in field values as '\|'
- Add a header-count assertion in event-format tests
When it happens
Trigger: Input starts with 'CEF:' but contains fewer or more than 6 unescaped pipe separators before the extension block. Line 320 check (headers.size() != 7) fires.
Common situations: Producer omits an empty field (writes 'CEF:0|v|p||1.0|...' missing a pipe); unescaped pipe inside a field value; extra trailing pipe; version of producer with non-standard field count.
Related errors
- Invalid CEF format
- Error parsing document in field [{}]
- Illegal escape sequence '\{}'
- Invalid extensions in the CEF event: {}
- CEF extensions contain unescaped equals sign
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/9d470b7f1b1a6067.
Report an issue: GitHub.