{"record":{"id":"22de61cd09534f9f","repo":"elastic/elasticsearch","slug":"numeric-value-length-length-exceeds-the-maxim","errorCode":null,"errorMessage":"Numeric value length [${length}] exceeds the maximum of [${MAX_NUMERIC_STRING_LENGTH}]","messagePattern":"Numeric value length \\[(.+?)\\] exceeds the maximum of \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/x-content/src/main/java/org/elasticsearch/xcontent/support/AbstractXContentParser.java","lineNumber":195,"sourceCode":"            return parseInt(numericText.string());\n        }\n        int result = doIntValue();\n        ensureNumberConversion(coerce, result, Integer.class);\n        return result;\n    }\n\n    protected abstract int doIntValue() throws IOException;\n\n    private static final BigInteger LONG_MAX_VALUE_AS_BIGINTEGER = BigInteger.valueOf(Long.MAX_VALUE);\n    private static final BigInteger LONG_MIN_VALUE_AS_BIGINTEGER = BigInteger.valueOf(Long.MIN_VALUE);\n\n    // Numeric strings longer than this are rejected before coercion, whose cost grows with the digit count;\n    // matches the unquoted JSON number-token limit. Mirrored by Numbers#MAX_NUMERIC_STRING_LENGTH. Keep in sync.\n    public static final int MAX_NUMERIC_STRING_LENGTH = 1000;\n\n    private static void checkNumericStringLength(int length) {\n        if (length > MAX_NUMERIC_STRING_LENGTH) {\n            throw new IllegalArgumentException(\n                \"Numeric value length [\" + length + \"] exceeds the maximum of [\" + MAX_NUMERIC_STRING_LENGTH + \"]\"\n            );\n        }\n    }\n\n    /**\n     * Returns the {@code long} that {@code stringValue} represents, using the same semantics as the\n     * document-indexing path ({@code longValue(coerce)}).\n     *\n     * <p>Plain integer strings are parsed via {@link Long#parseLong}; strings that cannot be parsed\n     * that way (decimals, scientific notation, big integers) fall back to {@link java.math.BigDecimal}.\n     * A fractional part is truncated when {@code coerce=true} and rejected with\n     * {@link IllegalArgumentException} when {@code coerce=false}. Values outside\n     * [{@link Long#MIN_VALUE}, {@link Long#MAX_VALUE}] always throw.\n     */\n    public static long toLong(String stringValue, boolean coerce) {\n        try {\n            return Long.parseLong(stringValue);","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/x-content/src/main/java/org/elasticsearch/xcontent/support/AbstractXContentParser.java#L177-L213","documentation":"Thrown by AbstractXContentParser.checkNumericStringLength() when the text length of a numeric string exceeds MAX_NUMERIC_STRING_LENGTH (1000 characters). This guard rejects pathologically long numeric strings before attempting expensive coercion via Double.parseDouble or BigDecimal, which would have O(n) or worse cost proportional to digit count. The limit mirrors the unquoted JSON number-token limit.","triggerScenarios":"Providing a numeric field value whose string representation exceeds 1000 characters, such as a number with hundreds of digits or an extremely long fractional part. This can happen with untrusted input, adversarial payloads, or bugs that produce very long numeric strings.","commonSituations":"Adversarial or malformed input sending very long numbers to exhaust server resources. Accidental generation of extremely long numeric strings (e.g., a serialization bug producing repeated digits). Scientific notation with a very long mantissa.","solutions":["Validate the numeric string length client-side and reject values longer than 1000 characters.","If the value is genuinely a large number, use a string field type (keyword or text) instead of a numeric type.","Sanitize or truncate untrusted numeric input before indexing.","Investigate the source of the overlong numeric string; it is likely a bug or an attack."],"exampleFix":"// before — overlong numeric string\n{ \"big_number\": \"123456789012345...<1000+ digits>...\" }\n\n// after — store as keyword string if large numbers are needed\nPUT /my-index/_mapping\n{ \"properties\": { \"big_number\": { \"type\": \"keyword\" } } }","handlingStrategy":"validation","validationCode":"// Before sending, verify numeric strings are within the length limit\nprivate static final int MAX_NUMERIC_LEN = 1000;\npublic static void validateNumericStringLength(Object value, String fieldName) {\n    String str = (value instanceof Number) ? value.toString() : String.valueOf(value);\n    if (str.length() > MAX_NUMERIC_LEN) {\n        throw new IllegalArgumentException(fieldName + \" numeric value length \" + str.length() + \" exceeds max of \" + MAX_NUMERIC_LEN);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    parser.longValue();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"exceeds the maximum\")) {\n        throw new BadRequestException(\"Numeric value too long; use a string field type for large numbers\");\n    }\n    throw e;\n}","preventionTips":["Validate the string length of numeric values client-side; reject anything over 1000 characters.","For genuinely large numbers, use keyword/text field types instead of numeric types.","Sanitize untrusted input that could contain adversarial overlong numeric strings."],"tags":["parsing","xcontent","numeric","input-validation","dos-prevention","length-limit"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}