projectdiscovery/nuclei · error
could not compile regex: %s
Error message
could not compile regex: %s
What it means
Template compilation error from Matcher.CompileMatchers (pkg/operators/matchers/compile.go:53). Each entry of the matcher's `regex:` list is compiled with the stdlib RE2 regexp.Compile (with a shared cache). Unparseable patterns abort matcher compilation with the offending pattern.
Source
Thrown at pkg/operators/matchers/compile.go:53
// Validate the matcher structure
if err := matcher.Validate(); err != nil {
return err
}
// By default, match on body if user hasn't provided any specific items
if matcher.Part == "" && matcher.GetType() != DSLMatcher {
matcher.Part = "body"
}
// Compile the regexes (with shared cache)
for _, regex := range matcher.Regex {
if cached, err := cache.Regex().GetIFPresent(regex); err == nil && cached != nil {
matcher.regexCompiled = append(matcher.regexCompiled, cached)
continue
}
compiled, err := regexp.Compile(regex)
if err != nil {
return fmt.Errorf("could not compile regex: %s", regex)
}
_ = cache.Regex().Set(regex, compiled)
matcher.regexCompiled = append(matcher.regexCompiled, compiled)
}
// Compile and validate binary Values in matcher
for _, value := range matcher.Binary {
if decoded, err := hex.DecodeString(value); err != nil {
return fmt.Errorf("could not hex decode binary: %s", value)
} else {
matcher.binaryDecoded = append(matcher.binaryDecoded, string(decoded))
}
}
// Compile the dsl expressions (with shared cache)
for _, dslExpression := range matcher.DSL {
if cached, err := cache.DSL().GetIFPresent(dslExpression); err == nil && cached != nil {
matcher.dslCompiled = append(matcher.dslCompiled, cached)View on GitHub (pinned to 265b3a3dec)
Solutions
- Test each regex with Go's RE2 engine (regex101 'golang' flavor) and fix/remove unsupported constructs
- In YAML prefer single-quoted strings so \d, \s, \+ pass through verbatim
- When a regex is composed from variables, escape interpolated values (regexp.QuoteMeta equivalent in DSL: `re_quote` if available, or precompute)
- Run `nuclei -validate -t template.yaml` to get the exact failing pattern
Example fix
# before regex: - '(?<=v)1\.\d+' # after regex: - 'v(1\.\d+)'
Defensive patterns
Strategy: validation
Validate before calling
for _, r := range m.Regex {
if _, err := regexp.Compile(r); err != nil {
return fmt.Errorf("bad matcher regex %q: %w", r, err)
}
} Type guard
func matcherRegexCompiles(pattern string) bool { _, err := regexp.Compile(pattern); return err == nil } Try / catch
if err := m.CompileMatchers(); err != nil && strings.Contains(err.Error(), "could not compile regex") {
// pull pattern from message; flag RE2 incompatibility (backrefs/lookarounds)
} Prevention
- Author regexes against RE2 semantics (golang flavor testers)
- Single-quote YAML regex strings to protect escapes
- Escape dynamic fragments before splicing them into patterns
When it happens
Trigger: A matcher regex containing PCRE-only constructs (backreferences \1, lookarounds (?=...) (?<=...)) or syntax errors such as unbalanced parens, a dangling '*', or an invalid escape.
Common situations: Copying detection regexes written for PCRE (Snort/ModSecurity/Python rules) into templates; YAML double-quote escaping eating backslashes ("\d" becomes literal 'd' issues); partially rendered dynamic regexes (e.g. payloads with regex metachars).
Related errors
- could not compile regex: %s
- regex extractor group must be >= 0, got %d
- unknown matcher type specified: %s
- could not hex decode binary: %s
- unknown condition specified: %s
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/8e435f5b07be83ef.
Report an issue: GitHub.