projectdiscovery/nuclei · error

could not compile regex: %s

Error message

could not compile regex: %s

What it means

Template compilation error from Extractor.CompileExtractors (pkg/operators/extractors/compile.go:35). Each entry of the extractor's `regex:` list is compiled with the standard library regexp.Compile (after consulting the shared regex cache). A pattern Go's RE2 engine cannot parse returns this error naming the offending pattern.

Source

Thrown at pkg/operators/extractors/compile.go:35

	computedType, err := toExtractorTypes(e.GetType().String())
	if err != nil {
		return fmt.Errorf("unknown extractor type specified: %s", e.Type)
	}
	e.extractorType = computedType

	if e.extractorType == RegexExtractor && e.RegexGroup < 0 {
		return fmt.Errorf("regex extractor group must be >= 0, got %d", e.RegexGroup)
	}

	// Compile the regexes
	for _, regex := range e.Regex {
		if cached, err := cache.Regex().GetIFPresent(regex); err == nil && cached != nil {
			e.regexCompiled = append(e.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)
		e.regexCompiled = append(e.regexCompiled, compiled)
	}
	for i, kval := range e.KVal {
		e.KVal[i] = strings.ToLower(kval)
	}

	for _, query := range e.JSON {
		query, err := gojq.Parse(query)
		if err != nil {
			return fmt.Errorf("could not parse json: %s", query)
		}
		compiled, err := gojq.Compile(query)
		if err != nil {
			return fmt.Errorf("could not compile json: %s", query)
		}
		e.jsonCompiled = append(e.jsonCompiled, compiled)

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Test the pattern standalone with Go regexp: `go run` a one-liner or use an RE2-compatible tester (e.g. regex101 with 'golang' flavor)
  2. Remove PCRE-only features: rewrite backreferences with capture + kval/dsl, lookaheads with separate matchers or a chained request
  3. Fix YAML quoting so backslashes survive: prefer single-quoted YAML strings with \d, \s literally
  4. Validate the template with `nuclei -validate -t <file>` which surfaces the exact failing regex

Example fix

# before (RE2 rejects backreference)
regex:
  - '(user|admin)-\1'
# after
regex:
  - 'user-user|admin-admin'
Defensive patterns

Strategy: validation

Validate before calling

import "regexp"

for _, r := range ex.Regex {
	if _, err := regexp.Compile(r); err != nil {
		return fmt.Errorf("bad extractor regex %q: %w", r, err)
	}
}

Type guard

func isRE2Compatible(pattern string) bool { _, err := regexp.Compile(pattern); return err == nil }

Try / catch

if err := ex.CompileExtractors(); err != nil {
	if strings.Contains(err.Error(), "could not compile regex") {
		// extract pattern from message, report with template path
	}
}

Prevention

When it happens

Trigger: A regex using constructs RE2 rejects: backreferences (\1), lookahead/lookbehind ((?=...), (?<=...)), arbitrary {n,m} repetition on unsupported constructs, or simple syntax errors like an unmatched ')' or '['.

Common situations: Porting PCRE patterns from Python/Perl/OWASP rules directly into a template; escaping mistakes in YAML single vs double quotes (e.g. '\d' vs "\d"); truncation of long patterns during copy-paste.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/9aa57170023abc99. Report an issue: GitHub.