{"record":{"id":"2d8b51487837a1eb","repo":"elastic/elasticsearch","slug":"pattern-is-referencing-a-non-existent-pattern","errorCode":null,"errorMessage":"pattern [{}] is referencing a non-existent pattern [{}]","messagePattern":"pattern \\[(.+?)\\] is referencing a non-existent pattern \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"libs/grok/src/main/java/org/elasticsearch/grok/PatternBank.java","lineNumber":181,"sourceCode":"            int begin = i + 2;\n            int bracketIndex = pattern.indexOf('}', begin);\n            int columnIndex = pattern.indexOf(':', begin);\n            int end;\n            if (bracketIndex != -1 && columnIndex == -1) {\n                end = bracketIndex;\n            } else if (columnIndex != -1 && bracketIndex == -1) {\n                end = columnIndex;\n            } else if (bracketIndex != -1) {\n                end = Math.min(bracketIndex, columnIndex);\n            } else {\n                throw new IllegalArgumentException(\"pattern [\" + pattern + \"] has an invalid syntax\");\n            }\n            String otherPatternName = pattern.substring(begin, end);\n            if (patternReferences.contains(otherPatternName) == false) {\n                patternReferences.add(otherPatternName);\n                String otherPattern = bank.get(otherPatternName);\n                if (otherPattern == null) {\n                    throw new IllegalArgumentException(\n                        \"pattern [\" + patternName + \"] is referencing a non-existent pattern [\" + otherPatternName + \"]\"\n                    );\n                }\n            }\n        }\n        return patternReferences.toArray(new String[0]);\n    }\n}\n","sourceCodeStart":163,"sourceCodeEnd":190,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/grok/src/main/java/org/elasticsearch/grok/PatternBank.java#L163-L190","documentation":"Thrown during cycle detection when a %{NAME} reference resolves to a name that is absent from the bank. getPatternNamesForPattern extracts the name between %{ and }/: and looks it up; a null lookup means the referenced pattern was never defined, so the bank is inconsistent and matching would silently fail.","triggerScenarios":"Constructing a PatternBank where a value references an undefined name, e.g. {\"A\":\"%{MISSING}\"} with no MISSING key. Also fires when a referenced pattern was removed from the map but a stale consumer still ships the old referencing pattern.","commonSituations":"Forgetting to bundle a base pattern (e.g. referencing %{IPV4} without including the stdlib IPV4 definition); renaming a pattern but not updating its callers; case mismatch (IPV4 vs ipv4); loading a subset of a pattern catalog that has external dependencies.","solutions":["The message names both the referencing pattern and the missing name: add an entry for the missing name, or fix the reference to point at an existing name.","Check for typos and case sensitivity in the referenced name (the lookup is exact Map.get).","If importing a standard grok pattern set, ensure all transitively referenced patterns from that set are included, not just the top-level entry.","If the reference is genuinely unused, delete the %{NAME} token from the pattern body."],"exampleFix":"// before\nMap<String,String> patterns = new HashMap<>();\npatterns.put(\"LOG\", \"%{IP:ip} %{WORD:user}\"); // IP and WORD undefined\nnew PatternBank(patterns); // throws: pattern [LOG] is referencing a non-existent pattern [IP]\n\n// after\npatterns.put(\"IP\", \"\\\\d{1,3}(\\\\.\\\\d{1,3}){3}\");\npatterns.put(\"WORD\", \"\\\\w+\");\npatterns.put(\"LOG\", \"%{IP:ip} %{WORD:user}\");\nnew PatternBank(patterns); // ok","handlingStrategy":"validation","validationCode":"// Verify every referenced name exists in the bank before construction.\nstatic java.util.List<String> missingRefs(java.util.Map<String,String> patterns) {\n    java.util.List<String> missing = new java.util.ArrayList<>();\n    java.util.regex.Pattern ref = java.util.regex.Pattern.compile(\"%\\\\{(\\\\w+)\");\n    for (var e : patterns.entrySet()) {\n        java.util.Matcher m = ref.matcher(e.getValue());\n        while (m.find()) {\n            if (!patterns.containsKey(m.group(1))) missing.add(e.getKey() + \" -> \" + m.group(1));\n        }\n    }\n    return missing;\n}","typeGuard":null,"tryCatchPattern":"try {\n    PatternBank bank = new PatternBank(patterns);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"referencing a non-existent pattern\")) {\n        // message names referencing pattern and missing name\n        reportConfigError(e.getMessage());\n    } else throw e;\n}","preventionTips":["Bundle the full standard grok set, not just the patterns you reference directly.","Use exact, case-sensitive names (IPV4 not ipv4).","Run a pre-flight missingRefs check over user-supplied pattern maps."],"tags":["grok","pattern","configuration","missing-reference"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T11:17:21.771Z"}