elastic/elasticsearch · error · IllegalArgumentException

failed to parse value [{}] for setting [{}], must be [-1b] (

Error message

failed to parse value [{}] for setting [{}], must be [-1b] (tracking disabled) or in the inclusive range [1b, 1gb]

What it means

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.

Source

Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/CompilerSettings.java:71

     * Per-context heuristic allocation limit, {@code script.painless.max_allocation_bytes.context.<context_name>.limit}.
     * The sentinel {@code -1b} (default) disables tracking; {@code [1b, 1gb]} enables it at that limit. {@link Property#NodeScope}
     * only, since the limit changes generated bytecode shape so a dynamic update would need a full compile-cache flush.
     */
    public static final Setting.AffixSetting<ByteSizeValue> MAX_ALLOCATION_BYTES = Setting.affixKeySetting(
        "script.painless.max_allocation_bytes.context.",
        "limit",
        key -> new Setting<>(key, MAX_ALLOCATION_BYTES_DISABLED.getStringRep(), s -> parseMaxAllocationBytes(s, key), Property.NodeScope)
    );

    /** Accepts the {@code -1b} sentinel or {@code [1b, 1gb]}; rejects {@code 0b} and (via {@link ByteSizeValue}) other negatives. */
    static ByteSizeValue parseMaxAllocationBytes(String value, String key) {
        ByteSizeValue parsed = ByteSizeValue.parseBytesSizeValue(value, key);
        long bytes = parsed.getBytes();
        if (bytes == MAX_ALLOCATION_BYTES_DISABLED.getBytes()) {
            return parsed;
        }
        if (bytes < 1L || bytes > MAX_ALLOCATION_BYTES_UPPER_BOUND.getBytes()) {
            throw new IllegalArgumentException(
                "failed to parse value ["
                    + value
                    + "] for setting ["
                    + key
                    + "], must be ["
                    + MAX_ALLOCATION_BYTES_DISABLED.getStringRep()
                    + "] (tracking disabled) or in the inclusive range [1b, "
                    + MAX_ALLOCATION_BYTES_UPPER_BOUND.getStringRep()
                    + "]"
            );
        }
        return parsed;
    }

    /**
     * Constant to be used when specifying the maximum loop counter when compiling a script.
     */
    public static final String MAX_LOOP_COUNTER = "max_loop_counter";

View on GitHub (pinned to db6a809a66)

Solutions

  1. To disable: use exactly '-1b'. To enable: use a value between '1b' and '1gb' inclusive, e.g. '64mb'.
  2. Double-check the unit suffix matches ByteSizeValue conventions (b, kb, mb, gb).
  3. If applying via API, send the value as a string with a unit, not a bare integer.

Example fix

// before
PUT _cluster/settings
{ "persistent": { "script.painless.max_allocation_bytes": "0b" } }
// after (disable)
{ "persistent": { "script.painless.max_allocation_bytes": "-1b" } }
// or (cap)
{ "persistent": { "script.painless.max_allocation_bytes": "256mb" } }
Defensive patterns

Strategy: validation

Validate before calling

function validateMaxAllocationBytes(v) {
  const m = /^(-?\d+(?:\.\d+)?)(b|kb|mb|gb)$/i.exec(String(v).trim());
  if (!m) throw new Error('Malformed byte size: ' + v);
  const bytes = parseFloat(m[1]) * { b:1, kb:1024, mb:1024**2, gb:1024**3 }[m[2].toLowerCase()];
  if (bytes === -1) return v; // disabled sentinel
  if (bytes < 1 || bytes > 1024**3) throw new Error('Must be -1b or in [1b, 1gb]');
  return v;
}

Prevention

When it happens

Trigger: 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'.

Common situations: 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.

Understand the failure class

Related errors


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