elastic/elasticsearch · error · IllegalArgumentException
Caught a StackOverflowError while processing gsub pattern: [
Error message
Caught a StackOverflowError while processing gsub pattern: [{}] What it means
Thrown by GsubProcessor.process when java.util.regex's replaceAll triggers a StackOverflowError on pathological regex/data combinations. The processor catches the SOE (a recoverable JVM error) and rethrows as IllegalArgumentException so the document fails this processor but ingest continues. The offending pattern is logged at TRACE; the value is deliberately not logged to avoid leaking sensitive data.
Source
Thrown at modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/GsubProcessor.java:68
String getReplacement() {
return replacement;
}
@Override
protected String process(String value) {
try {
return pattern.matcher(value).replaceAll(replacement);
} catch (StackOverflowError e) {
/*
* A bad regex on problematic data can trigger a StackOverflowError. In this case we can safely recover from the
* StackOverflowError, so we rethrow it as an Exception instead. This way the document fails this processor, but processing
* can carry on. The value would be useful to log here, but we do not do so for because we do not want to write potentially
* sensitive data to the logs.
*/
String message = "Caught a StackOverflowError while processing gsub pattern: [" + pattern + "]";
logger.trace(message, e);
throw new IllegalArgumentException(message);
}
}
@Override
public String getType() {
return TYPE;
}
public static final class Factory extends AbstractStringProcessor.Factory {
public Factory() {
super(TYPE);
}
@Override
protected GsubProcessor newProcessor(
String processorTag,
String description,View on GitHub (pinned to db6a809a66)
Solutions
- Rewrite the regex to avoid catastrophic backtracking (avoid nested quantifiers like (a+)+, anchor patterns, use possessive quantifiers).
- Increase JVM thread stack size (-Xss) as a stopgap for borderline inputs.
- Pre-truncate or sanitize overly long input strings before applying gsub.
- Test the regex in isolation against representative data before deploying.
Example fix
// before
{"gsub": {"field": "msg", "pattern": "(a+)+b", "replacement": "x"}}
// after
{"gsub": {"field": "msg", "pattern": "a+b", "replacement": "x"}} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-validate regex by testing on representative inputs with bounded length
try {
Pattern.compile(regex).matcher(sample).replaceAll(replacement);
} catch (StackOverflowError soe) {
// pattern is dangerous — reject at pipeline-create time
} Try / catch
try {
gsubProcessor.execute(doc);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("StackOverflowError while processing gsub pattern")) {
// route to failure store; flag the pattern for review
} else throw e;
} Prevention
- Avoid catastrophic-backtracking patterns (nested quantifiers like (a+)+).
- Test user-supplied regex against worst-case long inputs before deployment.
- Increase -Xss for the ingest JVM if patterns are borderline.
- Pre-truncate long input strings before gsub.
When it happens
Trigger: A gsub processor with a regex prone to catastrophic backtracking (e.g. nested quantifiers) running on a long or adversarial input string. JVM stack depth exceeded during NFA evaluation.
Common situations: User-supplied regex patterns not anchored/optimized, large unstructured text fields, pattern intended for short strings applied to whole documents, or upgrade of JDK changing regex engine behavior.
Related errors
- unexpected exception creating MessageDigest instance for [{}
- Invalid jvm argument `{}` configure as systemProperty instea
- Extra content ${message} ('${cutOutNoNl}') matching [${patte
- Didn't match ${pattern}: ${content}
- Unknown license for license file: {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/e39b1f2fe0571598.
Report an issue: GitHub.