{"record":{"id":"4c8bcba702934648","repo":"kestra-io/kestra","slug":"regextimeoutexception-e-getmessage-4c8bcb","errorCode":null,"errorMessage":"RegexTimeoutException: e.getMessage()","messagePattern":"RegexTimeoutException: e\\.getMessage\\(\\)","errorType":"exception","errorClass":"PebbleException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/io/kestra/core/runners/pebble/filters/ReplaceFilter.java","lineNumber":57,"sourceCode":"                null,\n                MessageFormat.format(\"The argument ''{0}'' is required.\", ARGUMENT_PAIRS), lineNumber,\n                self.getName()\n            );\n        }\n\n        final boolean regexp = args.containsKey(ARGUMENT_REGEXP) ? (Boolean) args.get(ARGUMENT_REGEXP) : false;\n        Map<?, ?> replacePair = (Map<?, ?>) args.get(ARGUMENT_PAIRS);\n\n        try {\n            if (input instanceof Map) {\n                return processMap((Map<String, Object>) input, replacePair, regexp);\n            } else if (input instanceof List) {\n                return processList((List<Object>) input, replacePair, regexp);\n            } else {\n                return processString(input.toString(), replacePair, regexp);\n            }\n        } catch (RegexUtils.RegexTimeoutException e) {\n            throw new PebbleException(e, e.getMessage(), lineNumber, self.getName());\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private Object processMap(Map<String, Object> inputMap, Map<?, ?> replacePair, boolean regexp) {\n        Map<String, Object> resultMap = new HashMap<>();\n        for (Map.Entry<String, Object> entry : inputMap.entrySet()) {\n            Object value = entry.getValue();\n            if (value instanceof String stringValue) {\n                resultMap.put(entry.getKey(), processString(stringValue, replacePair, regexp));\n            } else if (value instanceof Map) {\n                resultMap.put(entry.getKey(), processMap((Map<String, Object>) value, replacePair, regexp));\n            } else if (value instanceof List<?>) {\n                resultMap.put(entry.getKey(), processList((List<Object>) value, replacePair, regexp));\n            } else {\n                resultMap.put(entry.getKey(), processString(value.toString(), replacePair, regexp));\n            }\n        }","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/kestra-io/kestra/blob/823fada9274c4f9c251ea0a516460a4f7d958032/core/src/main/java/io/kestra/core/runners/pebble/filters/ReplaceFilter.java#L39-L75","documentation":"Thrown by the 'replace' Pebble filter when `regexp=true` is set and one of the find patterns in `replace_pairs` triggers catastrophic backtracking, raising `RegexUtils.RegexTimeoutException`. Kestra enforces a regex execution timeout to prevent ReDoS; exceeding it aborts the substitution.","triggerScenarios":"A find-pair key that is a vulnerable regex (e.g. `(a+)+`) applied to a long input; multiple regex pairs where any one backtracks explosively; user-controlled input flowing into the find key.","commonSituations":"Enabling `regexp=true` with patterns copy-pasted from elsewhere; large log/HTTP bodies processed with greedy nested quantifiers; not realizing keys are interpreted as regexes.","solutions":["If you do not need regex semantics, set `regexp=false` (the default) so keys are treated as literals.","Rewrite the vulnerable pattern to a linear-time equivalent.","Pre-truncate long input before substitution.","Audit each key in `replace_pairs` for nested unbounded quantifiers."],"exampleFix":"# before\n{{ body | replace(replace_pairs={\"(a+)+b\":\"x\"}, regexp=true) }}\n# after - literal match (no regex)\n{{ body | replace(replace_pairs={\"ab\":\"x\"}) }}","handlingStrategy":"validation","validationCode":"# Prefer literal mode; only enable regexp with audited patterns and short inputs:\n{% set safe = (body ?? \"\") | slice(0, 10000) %}\n{{ safe | replace(replace_pairs={\"a\":\"b\"}) }}  {# regexp defaults to false #}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set `regexp=false` (default) when keys are literal strings.","Rewrite regex keys to linear equivalents; avoid nested quantifiers.","Pre-truncate long input before substitution.","Audit each key for ReDoS potential."],"tags":["pebble-filter","replace","timeout","redos","performance","backtracking"],"backgroundTag":null,"analyzedSha":"823fada9274c4f9c251ea0a516460a4f7d958032","analyzedAt":"2026-08-14T06:15:17.947Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}