elastic/elasticsearch · error · IllegalArgumentException
cannot read binary value
Error message
cannot read binary value
What it means
Thrown by JsonProcessor.apply when the XContent parser emits a VALUE_EMBEDDED_OBJECT token, which means the input field contained a base64-decoded binary blob. JSON ingest does not support binary values at the top level, so the processor refuses. IllegalArgumentException guarding against binary content sneaking through.
Source
Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/JsonProcessor.java:114
)
) {
parser.allowDuplicateKeys(allowDuplicateKeys);
XContentParser.Token token = parser.nextToken();
Object value = null;
if (token == XContentParser.Token.VALUE_NULL) {
value = null;
} else if (token == XContentParser.Token.VALUE_STRING) {
value = parser.text();
} else if (token == XContentParser.Token.VALUE_NUMBER) {
value = parser.numberValue();
} else if (token == XContentParser.Token.VALUE_BOOLEAN) {
value = parser.booleanValue();
} else if (token == XContentParser.Token.START_OBJECT) {
value = parser.map();
} else if (token == XContentParser.Token.START_ARRAY) {
value = parser.list();
} else if (token == XContentParser.Token.VALUE_EMBEDDED_OBJECT) {
throw new IllegalArgumentException("cannot read binary value");
}
if (strictJsonParsing) {
String errorMessage = Strings.format(
"The input %s is not valid JSON and the %s parameter is true",
fieldValue,
STRICT_JSON_PARSING_PARAMETER
);
/*
* If strict JSON parsing is disabled, then once we've found the first token then we move on. For example for the string
* "123 \"foo\"" we would just return the first token, 123. However, if strict parsing is enabled (which it is by default),
* then we check to see whether there are any more tokens at this point. We expect the next token to be null. If there is
* another token or if the parser blows up, then we know we had invalid JSON and we alert the user with an
* IllegalArgumentException.
*/
try {
token = parser.nextToken();
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(errorMessage, e);View on GitHub (pinned to db6a809a66)
Solutions
- Ensure the source field contains a genuine JSON-encoded string, not binary.
- If binary content is expected, decode it before the json processor or use a different parser.
- Sanitize upstream producers that emit non-JSON content into the field.
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the source field is a plain string, not a binary-embedded value
Object v = ctx.get(fieldName);
if (v instanceof byte[]) {
throw new IllegalArgumentException("binary value not allowed for json processor");
} Type guard
static boolean isJsonSafe(Object v) {
return v == null || v instanceof String || v instanceof Number || v instanceof Boolean;
} Try / catch
try {
JsonProcessor.apply(value, allowDup, strict);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("cannot read binary value")) {
// route binary content elsewhere
} else throw e;
} Prevention
- Ensure upstream producers send JSON-encoded strings, not raw binary.
- Verify serialization format matches parser (JSON parser needs JSON content).
- Add a script processor to drop non-string values before the json processor.
When it happens
Trigger: The field passed to json ingest contains an embedded/binary object token (e.g. CBOR/SMILE binary content fed into the JSON parser, or a base64 value decoded by the parser).
Common situations: Mixed serialization formats (SMILE/CBOR fed to a JSON parser), corrupted input, or upstream producer emitting binary values where a string was expected.
Related errors
- cannot add non-map fields to root of document
- could not convert value of type [{}] to transport protocol
- field [{}] of type [{}] cannot be cast to a list or map
- The input {} is not valid JSON and the {} parameter is true
- <wrapped IOException>
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/e1008aef2ba4e523.
Report an issue: GitHub.