elastic/elasticsearch · error · IllegalArgumentException
For input string: "${stringValue}"
Error message
For input string: "${stringValue}" What it means
Thrown by AbstractXContentParser.toLong when the input string is not a parseable number at all — Long.parseLong fails and then `new BigDecimal(stringValue)` throws NumberFormatException. The catch block wraps it as an IllegalArgumentException. This is the catch-all for entirely non-numeric or malformed numeric input during long conversion.
Source
Thrown at libs/x-content/src/main/java/org/elasticsearch/xcontent/support/AbstractXContentParser.java:239
// long can have a maximum of 19 digits - any more than that cannot be a long
// the scale is stored as the negation, so negative scale -> big number
if (bigDecimalValue.scale() < -19) {
throw new IllegalArgumentException("Value [" + stringValue + "] is out of range for a long");
}
// large scale -> very small number
if (bigDecimalValue.scale() > 19) {
if (coerce) {
bigIntegerValue = BigInteger.ZERO;
} else {
throw new ArithmeticException("Number has a decimal part");
}
} else {
bigIntegerValue = coerce ? bigDecimalValue.toBigInteger() : bigDecimalValue.toBigIntegerExact();
}
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Value [" + stringValue + "] has a decimal part");
} catch (NumberFormatException e) {
throw new IllegalArgumentException("For input string: \"" + stringValue + "\"");
}
if (bigIntegerValue.compareTo(LONG_MAX_VALUE_AS_BIGINTEGER) > 0 || bigIntegerValue.compareTo(LONG_MIN_VALUE_AS_BIGINTEGER) < 0) {
throw new IllegalArgumentException("Value [" + stringValue + "] is out of range for a long");
}
assert bigIntegerValue.longValueExact() <= Long.MAX_VALUE; // asserting that no ArithmeticException is thrown
return bigIntegerValue.longValue();
}
@Override
public long longValue() throws IOException {
return longValue(DEFAULT_NUMBER_COERCE_POLICY);
}
@Override
public long longValue(boolean coerce) throws IOException {
Token token = currentToken();View on GitHub (pinned to db6a809a66)
Solutions
- Inspect the offending value in the error message and correct the producer to emit a clean integer string.
- Add an ingest pipeline with a script/grok processor to normalize the value before indexing.
- Re-map the field to keyword if the values are genuinely non-numeric identifiers or labels.
- If hex/scientific formats are expected, pre-convert them in your application code before submitting to Elasticsearch.
Example fix
// before: long field receives "1,000"
// after: strip separators in an ingest pipeline before the long field
PUT _ingest/pipeline/normalize { "processors": [ { "script": { "source": "ctx.amount = ctx.amount.replaceAll('[^0-9-]', '')" } } ] } Defensive patterns
Strategy: validation
Validate before calling
static boolean isNumeric(String s) {
if (s == null || s.isEmpty()) return false;
try { new java.math.BigDecimal(s); return true; }
catch (NumberFormatException e) { return false; }
} Try / catch
try { parser.longValue(coerce); }
catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("For input string:")) { /* log and reject the bad value */ }
else throw e;
} Prevention
- Sanitize locale-formatted numbers (strip thousands separators) before indexing.
- Use ingest pipelines to normalize numeric input.
- Detect numeric fields via sampling and re-map to keyword if values are non-numeric.
When it happens
Trigger: Calling longValue/longValue(coerce) on a VALUE_STRING token containing text like "abc", "12-34", "", "NaN", "0x1F", "1,000" (with separators), or a value with leading/trailing whitespace. Indexing a non-numeric string into a long-mapped field.
Common situations: Schema-less ingest where a field is auto-detected as long on early documents and later receives textual values. Locale-specific number formatting (commas as thousands separators) passed verbatim. Misconfigured ingest pipeline converting a date string into a field mapped as long. Log payloads mixing units ("42ms") into numeric fields.
Related errors
- Numeric value length [${length}] exceeds the maximum of [${M
- Value [${stringValue}] is out of range for a long
- Value [${stringValue}] has a decimal part
- ${clazz.getSimpleName()} value passed as String
- ${fullVal} cannot be converted to ${clazz.getSimpleName()} w
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/fa021c3449ec79b4.
Report an issue: GitHub.