elastic/elasticsearch · error · IllegalArgumentException
[{}] is not a boolean value, cannot convert to boolean
Error message
[{}] is not a boolean value, cannot convert to boolean What it means
Thrown by the ConvertProcessor BOOLEAN constant when the field value's string form is not case-insensitively equal to 'true' or 'false'. Unlike numeric conversions there is no underlying parse exception; the processor explicitly checks only those two literals and rejects everything else (including '1'/'0', 'yes'/'no', 'Y'/'N'). It fires during pipeline execution while converting a field to boolean.
Source
Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/ConvertProcessor.java:90
FLOAT {
@Override
public Object convert(Object value) {
try {
return Float.parseFloat(value.toString());
} catch (NumberFormatException e) {
throw new IllegalArgumentException("unable to convert [" + value + "] to float", e);
}
}
},
BOOLEAN {
@Override
public Object convert(Object value) {
if (value.toString().equalsIgnoreCase("true")) {
return true;
} else if (value.toString().equalsIgnoreCase("false")) {
return false;
} else {
throw new IllegalArgumentException("[" + value + "] is not a boolean value, cannot convert to boolean");
}
}
},
IP {
@Override
public Object convert(Object value) {
// IllegalArgumentException is thrown if unable to convert
InetAddresses.forString((String) value);
return value;
}
},
STRING {
@Override
public Object convert(Object value) {
return value.toString();
}
},
AUTO {View on GitHub (pinned to db6a809a66)
Solutions
- Normalize the field with a preceding 'gsub' or 'script' processor so the value is exactly 'true' or 'false' before the convert step.
- Use a 'script' processor with painless logic (e.g. ctx.flag = ['1','yes','y','true'].contains(ctx.flag?.toLowerCase()) ) as a replacement for convert.
- Correct the producing application to emit JSON booleans (true/false) rather than strings.
Example fix
// before - field "active" = "yes"
{"convert": {"field": "active", "type": "boolean"}}
// after - map common truthy strings first
{"script": {"source": "def v = ctx.active?.toString()?.toLowerCase(); ctx.active = (v == '1' || v == 'yes' || v == 'y' || v == 'true') ? 'true' : 'false'"}},
{"convert": {"field": "active", "type": "boolean"}} Defensive patterns
Strategy: validation
Validate before calling
// Pre-map common truthy/falsy strings before convert to boolean:
{"script": {"source": "def v = ctx.active?.toString()?.toLowerCase(); if (v != null) { ctx.active = (['1','yes','y','true','on'].contains(v)) ? 'true' : 'false'; }"}} Type guard
// painless guard
boolean isBooleanLiteral(def v) { def s = v?.toString()?.toLowerCase(); return 'true'.equals(s) || 'false'.equals(s); } Try / catch
// Use pipeline on_failure to quarantine non-boolean values:
{"on_failure": [{"set": {"field": "error", "value": "boolean-convert"}}, {"index": {"index": "ingest-dlq"}}]} Prevention
- Normalize Y/N, 1/0, yes/no upstream to literal 'true'/'false'.
- Prefer emitting JSON booleans from the producer when possible.
- Document the strict 'true'/'false' rule for pipeline authors.
When it happens
Trigger: A 'convert' processor with 'type: boolean' is run on a document whose target field is '1', '0', 'yes', 'no', 'Y', 't', 'enabled', or any value other than the literal strings 'true'/'false'.
Common situations: Migrating from a system that serializes booleans as 0/1 integers; CSV/log ingest where flags are Y/N; JSON producers that emit 'Yes'; legacy fields using 'ENABLED'/'DISABLED'.
Related errors
- unable to convert [{}] to float
- unable to parse {} [{}]
- unable to convert [{}] to integer
- unable to convert [{}] to long
- unable to convert [{}] to double
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/98f2a1580ee4fc3c.
Report an issue: GitHub.