elastic/elasticsearch · error · ClassCastException
cannot cast java.lang.String with length not equal to one to
Error message
cannot cast java.lang.String with length not equal to one to char
What it means
The companion check in Utility.StringTochar: the String is non-null but its length is not exactly 1, so it cannot be narrowed to a single char. Throws ClassCastException at script runtime.
Source
Thrown at modules/lang-painless/src/main/java/org/elasticsearch/painless/Utility.java:30
/**
* A set of methods for non-native boxing and non-native
* exact math operations used at both compile-time and runtime.
*/
public class Utility {
public static String charToString(final char value) {
return String.valueOf(value);
}
public static char StringTochar(final String value) {
if (value == null) {
throw new ClassCastException(
"cannot cast " + "null " + String.class.getCanonicalName() + " to " + char.class.getCanonicalName()
);
}
if (value.length() != 1) {
throw new ClassCastException(
"cannot cast " + String.class.getCanonicalName() + " with length not equal to one to " + char.class.getCanonicalName()
);
}
return value.charAt(0);
}
private Utility() {}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Guard the cast with a length check: str.length() == 1 ? (char)str : <fallback>.
- Constrain the source mapping/data so the value is always exactly one character.
- Use str.charAt(0) only after validating length.
Example fix
// before char c = (char)doc['code'].value; // 'AB' -> 1349 // after String s = doc['code'].value; char c = (s != null && s.length() == 1) ? (char)s : '\\0';
Defensive patterns
Strategy: validation
Validate before calling
// Inside the Painless script, guard before casting:
// String s = doc['code'].value;
// if (s != null && s.length() == 1) { char c = (char)s; } Type guard
// Painless-side guard String s = doc['code'].value; boolean isSingleChar = (s != null && s.length() == 1);
Try / catch
try {
scriptService.run(script, context, vars);
} catch (ScriptException e) {
if (e.getCause() instanceof ClassCastException ce && ce.getMessage().contains("length not equal to one")) {
log.warn("multi-char String-to-char in script");
}
throw e;
} Prevention
- Validate String length is exactly 1 before casting to char.
- Use a keyword mapping with a length constraint if the field feeds a char cast.
- Prefer explicit charAt(0) with a guard over an unchecked cast.
When it happens
Trigger: A Painless script casts a multi-character (or empty) String to char via (char)str; e.g. doc['code'].value where the field holds 'AB' or ''.
Common situations: Indexing free-text fields and then casting them to char in a script; runtime fields over string data whose length is not constrained to 1; bad test fixture data.
Related errors
- cannot cast null java.lang.String to char
- Cannot apply [-] operation to types [{}] and [{}].
- Cannot apply [<] operation to type [boolean]
- Cannot apply [<] operation to types [{}] and [{}].
- Cannot apply [<=] operation to type [boolean]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b11172e04a00f16b.
Report an issue: GitHub.