elastic/elasticsearch · error · IllegalArgumentException

<wrapped IOException>

Error message

<wrapped IOException>

What it means

JsonProcessor.apply wraps any IOException from the XContentParser in an IllegalArgumentException with the placeholder message. Since the parser reads from an in-memory string, an IOException indicates a parser-level fault rather than a real I/O issue. The original IOException is the cause of the thrown IllegalArgumentException.

Source

Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/JsonProcessor.java:140

                /*
                 * 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);
                }
                if (token != null) {
                    throw new IllegalArgumentException(errorMessage);
                }
            }
            return value;
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        }
    }

    public static void apply(
        Map<String, Object> ctx,
        String fieldName,
        boolean allowDuplicateKeys,
        ConflictStrategy conflictStrategy,
        boolean strictJsonParsing
    ) {
        Object value = apply(ctx.get(fieldName), allowDuplicateKeys, strictJsonParsing);
        mergeParsedJson(ctx, value, conflictStrategy);
    }

    private static void mergeParsedJson(Map<String, Object> ctx, Object value, ConflictStrategy conflictStrategy) {
        if (value instanceof Map) {
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (Map<String, Object>) value;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Inspect the wrapped IOException cause in server logs for the specific parser failure.
  2. Validate the input field is well-formed JSON before invoking the json processor.
  3. If the data is legitimately non-JSON, route it differently or pre-clean it.
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-validate JSON well-formedness with the same parser
try (XContentParser p = JsonXContent.jsonXContent.createParser(
        XContentParserConfiguration.EMPTY, value)) {
    while (p.nextToken() != null) {}
} catch (IOException ioe) {
    // value is not parseable — handle before invoking processor
}

Try / catch

try {
    JsonProcessor.apply(value, allowDup, strict);
} catch (IllegalArgumentException e) {
    if (e.getCause() instanceof IOException) {
        // log cause and route to failure store
    } else throw e;
}

Prevention

When it happens

Trigger: The JSON parser threw an IOException parsing the fieldValue string — typically malformed JSON that fails during tokenization rather than grammar validation.

Common situations: Truncated or corrupted JSON in the field, encoding issues (non-UTF8 bytes decoded wrongly), or parser bugs.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/66a6abeb20f55ec0. Report an issue: GitHub.