elastic/elasticsearch · error · IllegalArgumentException
pattern [{}] has an invalid syntax
Error message
pattern [{}] has an invalid syntax What it means
Thrown while expanding pattern references during cycle detection. getPatternNamesForPattern scans each pattern for %{ tokens; if it finds a %{ with no following } or : it cannot determine the referenced name and rejects the pattern as syntactically malformed. This guards against unterminated grok substitution markers before any matching is attempted.
Source
Thrown at libs/grok/src/main/java/org/elasticsearch/grok/PatternBank.java:174
* are found, an empty array is returned. If any of the list of pattern names to be returned does not exist in the bank, an exception
* is thrown.
*/
private static String[] getPatternNamesForPattern(Map<String, String> bank, String patternName) {
String pattern = bank.get(patternName);
List<String> patternReferences = new ArrayList<>();
for (int i = pattern.indexOf("%{"); i != -1; i = pattern.indexOf("%{", i + 1)) {
int begin = i + 2;
int bracketIndex = pattern.indexOf('}', begin);
int columnIndex = pattern.indexOf(':', begin);
int end;
if (bracketIndex != -1 && columnIndex == -1) {
end = bracketIndex;
} else if (columnIndex != -1 && bracketIndex == -1) {
end = columnIndex;
} else if (bracketIndex != -1) {
end = Math.min(bracketIndex, columnIndex);
} else {
throw new IllegalArgumentException("pattern [" + pattern + "] has an invalid syntax");
}
String otherPatternName = pattern.substring(begin, end);
if (patternReferences.contains(otherPatternName) == false) {
patternReferences.add(otherPatternName);
String otherPattern = bank.get(otherPatternName);
if (otherPattern == null) {
throw new IllegalArgumentException(
"pattern [" + patternName + "] is referencing a non-existent pattern [" + otherPatternName + "]"
);
}
}
}
return patternReferences.toArray(new String[0]);
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Open the named pattern shown in the message and find the %{ that has no matching } or : before the next %{ or end of string.
- Close the reference (%{NAME}) or convert the literal %{ into a regex-escaped form if it was not meant as a substitution.
- Validate patterns with a quick check (every %{ is followed by a } or :) before passing them to PatternBank.
Example fix
// before
Map<String,String> patterns = Map.of(
"BAD", "time=%{TIMESTAMP ms" // missing closing }");
new PatternBank(patterns); // throws: pattern [...] has an invalid syntax
// after
Map<String,String> patterns = Map.of(
"BAD", "time=%{TIMESTAMP:ms}");
new PatternBank(patterns); // ok Defensive patterns
Strategy: validation
Validate before calling
// Reject patterns with unterminated %{ references before building the bank.
static boolean syntaxOk(java.util.Map<String,String> patterns) {
java.util.regex.Pattern unterminated =
java.util.regex.Pattern.compile("%\\{[^}]*$"); // %{ with no } before end-of-line
for (var e : patterns.entrySet()) {
if (unterminated.matcher(e.getValue()).find()) return false;
// also reject %{ with neither } nor : after it on the same line
java.util.regex.Matcher m = java.util.regex.Pattern.compile("%\\{([^}:])*").matcher(e.getValue());
// (full validation mirrors PatternBank; simplest is to try-construct)
}
return true;
} Try / catch
try {
PatternBank bank = new PatternBank(patterns);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("has an invalid syntax")) {
reportConfigError("malformed grok pattern: " + e.getMessage());
} else throw e;
} Prevention
- For every %{ in a pattern, ensure a matching } or : on the same line.
- Escape literal %{ as \\%{ if it is regex text, not a substitution.
- Lint patterns in CI by constructing a PatternBank before merging catalog changes.
When it happens
Trigger: Constructing a PatternBank whose map contains a value with an unterminated reference, e.g. "FOO": "prefix %{BAR more text" (no closing brace) or a lone "%{" in a pattern body. The parser found %{ but indexOf('}') and indexOf(':') after it both returned -1.
Common situations: Hand-editing a grok pattern and deleting the closing brace; a regex that legitimately needs a literal %{ without intending a substitution (must escape or restructure); truncated/copy-pasted pattern files missing the tail of a line.
Related errors
- circular reference detected: {}
- pattern [{}] is referencing a non-existent pattern [{}]
- unsupported ECS compatibility mode [{}]
- field [{}] is null, cannot process it.
- unsupported ECS compatibility mode [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b55176cfe3ba8d8a.
Report an issue: GitHub.