elastic/elasticsearch · error · IllegalArgumentException

Unable to find pattern [{}] in Grok's pattern dictionary

Error message

Unable to find pattern [{}] in Grok's pattern dictionary

What it means

Thrown by Grok.toRegex() during pattern compilation when a named pattern referenced via %{PATTERN_NAME:...} or %{PATTERN_NAME} is not found in the provided PatternBank. The Grok constructor calls toRegex() to expand all grok pattern references into a concrete regular expression. Each %{NAME} must resolve to an entry in the pattern bank.

Source

Thrown at libs/grok/src/main/java/org/elasticsearch/grok/Grok.java:148

                result = matcher.search(0, grokPatternBytes.length, Option.NONE);
            } finally {
                matcherWatchdog.unregister(matcher);
            }
            handleInterrupted(result);
            if (result < 0) {
                return res.append(grokPattern).toString();
            }

            Region region = matcher.getEagerRegion();
            String namedPatternRef = groupMatch(NAME_GROUP, region, grokPattern);
            String subName = groupMatch(SUBNAME_GROUP, region, grokPattern);
            // TODO(tal): Support definitions
            @SuppressWarnings("unused")
            String definition = groupMatch(DEFINITION_GROUP, region, grokPattern);
            String patternName = groupMatch(PATTERN_GROUP, region, grokPattern);
            String pattern = patternBank.get(patternName);
            if (pattern == null) {
                throw new IllegalArgumentException("Unable to find pattern [" + patternName + "] in Grok's pattern dictionary");
            }
            if (pattern.contains("%{" + patternName + "}") || pattern.contains("%{" + patternName + ":")) {
                throw new IllegalArgumentException("circular reference in pattern back [" + patternName + "]");
            }
            String grokPart;
            if (namedCaptures && subName != null) {
                grokPart = String.format(Locale.US, "(?<%s>%s)", namedPatternRef, pattern);
            } else if (namedCaptures) {
                grokPart = String.format(Locale.US, "(?:%s)", pattern);
            } else {
                grokPart = String.format(Locale.US, "(?<%s>%s)", patternName + "_" + result, pattern);
            }
            String start = new String(grokPatternBytes, 0, result, StandardCharsets.UTF_8);
            String rest = new String(
                grokPatternBytes,
                region.getEnd(0),
                grokPatternBytes.length - region.getEnd(0),
                StandardCharsets.UTF_8

View on GitHub (pinned to db6a809a66)

Solutions

  1. Pre-register the missing pattern in the PatternBank before constructing the Grok object.
  2. Use GrokBuiltinPatterns.legacyPatterns() or ecsV1Patterns() to include standard built-in patterns.
  3. Check the spelling of the pattern name in the grok expression — compare against the pattern definitions file.
  4. Merge custom patterns with built-in patterns: create a combined PatternBank with both sets.

Example fix

// before — missing pattern
Map<String, String> custom = Map.of("MYCUSTOM", "\\d+");
PatternBank bank = new PatternBank(custom);
new Grok(bank, "%{IP:client_ip} %{MYCUSTOM:count}", null); // IP not in bank

// after — merge with built-in patterns
Map<String, String> custom = new LinkedHashMap<>(GrokBuiltinPatterns.legacyPatterns().patterns());
custom.put("MYCUSTOM", "\\d+");
PatternBank bank = new PatternBank(custom);
new Grok(bank, "%{IP:client_ip} %{MYCUSTOM:count}", null);
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check that all referenced patterns exist in the bank
String[] refs = extractPatternReferences(grokPattern); // your utility
for (String ref : refs) {
    if (patternBank.get(ref) == null) {
        throw new IllegalArgumentException("Missing grok pattern: " + ref);
    }
}
new Grok(patternBank, grokPattern, callback);

Type guard

static boolean allPatternsDefined(String grokPattern, PatternBank bank) {
    // simplistic check — a full check requires parsing %{NAME} references
    java.util.regex.Pattern ref = java.util.regex.Pattern.compile("%\\{(\\w+)");
    var m = ref.matcher(grokPattern);
    while (m.find()) {
        if (bank.get(m.group(1)) == null) return false;
    }
    return true;
}

Try / catch

try {
    new Grok(patternBank, grokPattern, callback);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Unable to find pattern")) {
        // extract pattern name, suggest registering it or merging built-in patterns
    }
    throw e;
}

Prevention

When it happens

Trigger: Constructing a new Grok(patternBank, grokPattern) where grokPattern contains a %{PATTERN_NAME} reference that does not exist in patternBank. Common with custom patterns that reference built-in pattern names that are only available in a specific ECS compatibility mode, or when the pattern bank was built with a different set of patterns.

Common situations: Using a grok pattern that references %{IP} or %{NUMBER} but loading patterns with a custom PatternBank that doesn't include those; misspelling a pattern name (e.g. %{IPORHOST} vs %{IPOR_HOST}); ECS v1 vs legacy pattern mismatch — some patterns exist only in one mode; using a third-party grok pattern file that references patterns not in the Elasticsearch built-in set.

Related errors


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