{"record":{"id":"ad993dddf9e0ab74","repo":"elastic/elasticsearch","slug":"failed-to-parse-value-for-setting-must","errorCode":null,"errorMessage":"failed to parse value [{}] for setting [{}], must be [-1b] (tracking disabled) or in the inclusive range [1b, 1gb]","messagePattern":"failed to parse value \\[(.+?)\\] for setting \\[(.+?)\\], must be \\[-1b\\] \\(tracking disabled\\) or in the inclusive range \\[1b, 1gb\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java","lineNumber":71,"sourceCode":"     * Per-context heuristic allocation limit, {@code script.painless.max_allocation_bytes.context.<context_name>.limit}.\n     * The sentinel {@code -1b} (default) disables tracking; {@code [1b, 1gb]} enables it at that limit. {@link Property#NodeScope}\n     * only, since the limit changes generated bytecode shape so a dynamic update would need a full compile-cache flush.\n     */\n    public static final Setting.AffixSetting<ByteSizeValue> MAX_ALLOCATION_BYTES = Setting.affixKeySetting(\n        \"script.painless.max_allocation_bytes.context.\",\n        \"limit\",\n        key -> new Setting<>(key, MAX_ALLOCATION_BYTES_DISABLED.getStringRep(), s -> parseMaxAllocationBytes(s, key), Property.NodeScope)\n    );\n\n    /** Accepts the {@code -1b} sentinel or {@code [1b, 1gb]}; rejects {@code 0b} and (via {@link ByteSizeValue}) other negatives. */\n    static ByteSizeValue parseMaxAllocationBytes(String value, String key) {\n        ByteSizeValue parsed = ByteSizeValue.parseBytesSizeValue(value, key);\n        long bytes = parsed.getBytes();\n        if (bytes == MAX_ALLOCATION_BYTES_DISABLED.getBytes()) {\n            return parsed;\n        }\n        if (bytes < 1L || bytes > MAX_ALLOCATION_BYTES_UPPER_BOUND.getBytes()) {\n            throw new IllegalArgumentException(\n                \"failed to parse value [\"\n                    + value\n                    + \"] for setting [\"\n                    + key\n                    + \"], must be [\"\n                    + MAX_ALLOCATION_BYTES_DISABLED.getStringRep()\n                    + \"] (tracking disabled) or in the inclusive range [1b, \"\n                    + MAX_ALLOCATION_BYTES_UPPER_BOUND.getStringRep()\n                    + \"]\"\n            );\n        }\n        return parsed;\n    }\n\n    /**\n     * Constant to be used when specifying the maximum loop counter when compiling a script.\n     */\n    public static final String MAX_LOOP_COUNTER = \"max_loop_counter\";","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java#L53-L89","documentation":"CompilerSettings.parseMaxAllocationBytes validates the 'script.painless.max_allocation_bytes' Setting. It first parses via ByteSizeValue (which rejects malformed units and most negatives), then enforces a domain rule: the value must be exactly the disabled sentinel -1b OR fall in the inclusive range [1b, 1gb]. Zero bytes and any value below 1b or above 1gb are rejected even though ByteSizeValue accepted the syntax.","triggerScenarios":"Setting script.painless.max_allocation_bytes in elasticsearch.yml or via the cluster settings API to a disallowed value: '0b', '0', a fractional like '0.5b', a negative other than -1b (e.g. '-2b' — caught earlier by ByteSizeValue), or an over-limit value like '2gb' or '2048mb'.","commonSituations":"Disabling the guard by setting 0 instead of -1b. Copying a heap-size value into the allocation setting. Units confusion (kb vs kb binary). Setting the value via API with a bare number string.","solutions":["To disable: use exactly '-1b'. To enable: use a value between '1b' and '1gb' inclusive, e.g. '64mb'.","Double-check the unit suffix matches ByteSizeValue conventions (b, kb, mb, gb).","If applying via API, send the value as a string with a unit, not a bare integer."],"exampleFix":"// before\nPUT _cluster/settings\n{ \"persistent\": { \"script.painless.max_allocation_bytes\": \"0b\" } }\n// after (disable)\n{ \"persistent\": { \"script.painless.max_allocation_bytes\": \"-1b\" } }\n// or (cap)\n{ \"persistent\": { \"script.painless.max_allocation_bytes\": \"256mb\" } }","handlingStrategy":"validation","validationCode":"function validateMaxAllocationBytes(v) {\n  const m = /^(-?\\d+(?:\\.\\d+)?)(b|kb|mb|gb)$/i.exec(String(v).trim());\n  if (!m) throw new Error('Malformed byte size: ' + v);\n  const bytes = parseFloat(m[1]) * { b:1, kb:1024, mb:1024**2, gb:1024**3 }[m[2].toLowerCase()];\n  if (bytes === -1) return v; // disabled sentinel\n  if (bytes < 1 || bytes > 1024**3) throw new Error('Must be -1b or in [1b, 1gb]');\n  return v;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate the setting string before applying via API or writing to elasticsearch.yml.","Use -1b (never 0b) to disable.","Keep units explicit (mb/gb)."],"tags":["painless","settings","configuration","byte-size","validation"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}