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

  1. Rewrite the regex to avoid catastrophic backtracking (avoid nested quantifiers like (a+)+, anchor patterns, use possessive quantifiers).
  2. Increase JVM thread stack size (-Xss) as a stopgap for borderline inputs.
  3. Pre-truncate or sanitize overly long input strings before applying gsub.
  4. 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

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


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