trufflesecurity/trufflehog · error
%s is not a valid regex, error received: %v
Error message
%s is not a valid regex, error received: %v
What it means
TruffleHog's JDBC detector exposes WithIgnorePattern as a functional option: it takes a slice of regex strings used to suppress false-positive JDBC connection strings, compiles each one with Go's stdlib regexp package, and panics with this message as soon as regexp.Compile fails. The panic fires when New(...) applies the option, i.e. at scanner construction time, before any scanning happens. The message embeds both the offending pattern and the compiler's reason, so the panic text is the diagnosis.
Source
Thrown at pkg/detectors/jdbc/jdbc.go:39
func New(opts ...func(*Scanner)) *Scanner {
scanner := &Scanner{
ignorePatterns: []regexp.Regexp{},
}
for _, opt := range opts {
opt(scanner)
}
return scanner
}
func WithIgnorePattern(ignoreStrings []string) func(*Scanner) {
return func(s *Scanner) {
var ignorePatterns []regexp.Regexp
for _, ignoreString := range ignoreStrings {
ignorePattern, err := regexp.Compile(ignoreString)
if err != nil {
panic(fmt.Sprintf("%s is not a valid regex, error received: %v", ignoreString, err))
}
ignorePatterns = append(ignorePatterns, *ignorePattern)
}
s.ignorePatterns = ignorePatterns
}
}
// Ensure the Scanner satisfies the interface at compile time.
var _ detectors.Detector = (*Scanner)(nil)
var _ detectors.CustomFalsePositiveChecker = (*Scanner)(nil)
var (
// Matches typical JDBC connection strings.
// The terminal character class additionally excludes () and & to avoid
// capturing surrounding delimiters (e.g. "(jdbc:…)" or "…&user=x&").
keyPat = regexp.MustCompile(`(?i)jdbc:[\w]{3,10}:[^\s"'<>,{}[\]]{10,511}[^\s"'<>,{}[\]()&]`)
)View on GitHub (pinned to bcfcf73aaf)
Solutions
- Read the panic string: it names the exact bad pattern and the compiler error (e.g. 'missing closing )'); fix that specific pattern first.
- If the pattern was copied from a glob/PCRE tool, convert it: '*.internal.example.com' -> `.*\.internal\.example\.com`, and escape regex metacharacters ( . + ? ( ) [ ] { } | ^ $ ).
- Write patterns as Go raw string literals (backticks) so you write one backslash instead of two and avoid escaping mistakes in interpreted strings.
- Validate the whole pattern list with regexp.Compile at your config boundary and return a normal error, instead of letting the library panic at startup.
- If patterns are fully untrusted and you cannot validate upstream, wrap the New() call in a defer/recover to convert the panic into an error.
Example fix
// before
s := jdbc.New(jdbc.WithIgnorePattern([]string{"jdbc:mysql://*.stage.example.com"})) // panics: '*' has nothing to repeat
// after
s := jdbc.New(jdbc.WithIgnorePattern([]string{`jdbc:mysql://.*\.stage\.example\.com`})) Defensive patterns
Strategy: validation
Validate before calling
import (
"fmt"
"regexp"
)
// Run BEFORE jdbc.New(jdbc.WithIgnorePattern(...)). Uses stdlib regexp,
// the same engine the jdbc detector compiles with.
func compileIgnorePatterns(patterns []string) ([]*regexp.Regexp, error) {
compiled := make([]*regexp.Regexp, 0, len(patterns))
for _, p := range patterns {
re, err := regexp.Compile(p)
if err != nil {
return nil, fmt.Errorf("invalid jdbc ignore pattern %q: %w", p, err)
}
compiled = append(compiled, re)
}
return compiled, nil
}
if _, err := compileIgnorePatterns(cfg.JdbcIgnorePatterns); err != nil {
return err // fail config validation, never reach jdbc.New()
} Type guard
// True when the string is safely passable to jdbc.WithIgnorePattern.
func isValidIgnorePattern(pattern string) bool {
_, err := regexp.Compile(pattern)
return err == nil
} Try / catch
// Last-resort conversion of the constructor panic into an error.
func newJdbcScanner(opts ...func(*jdbc.Scanner)) (sc *jdbc.Scanner, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("jdbc scanner construction failed: %v", r)
}
}()
return jdbc.New(opts...), nil
} Prevention
- Compile-check every ignore pattern with regexp.Compile at config load time and return an error there — never let raw config strings reach New() untested.
- Remember the jdbc detector uses Go stdlib regexp (RE2 syntax): no lookaheads, lookbehinds, or backreferences are accepted.
- Write patterns as raw string literals (backticks) so each regex escape is one backslash, not two.
- Do not paste globs (*.example.com) or PCRE into the pattern list; convert wildcards to .* and escape metacharacters.
- Add a unit test that compiles your pattern list (mirror TestJdbc_FromDataWithIgnorePattern) so bad patterns fail CI, not production.
When it happens
Trigger: Calling jdbc.New(jdbc.WithIgnorePattern([]string{...})) where at least one string is not compilable by Go's RE2-based regexp: unbalanced '(' or '[', a trailing backslash, a repetition operator with nothing to repeat (e.g. '*.example.com' or '+foo'), an invalid named group like '(?P<>', or a reverse character range like '[z-a]'. The panic happens inside the option closure that New() invokes, so the crash occurs on the New() call line, not during FromData().
Common situations: Embedding trufflehog as a library and feeding ignore patterns from CLI flags, env vars, or CI config without pre-validation; copying glob patterns from .gitignore-style configs ('*.internal.example.com') into a regex field; under- or over-escaping in interpreted string literals ("\." vs "\\." vs "\\\\."); hand-editing a pattern list and shipping without running the detector tests (TestJdbc_FromDataWithIgnorePattern exercises this option).
Related errors
AI-assisted analysis of trufflesecurity/trufflehog@bcfcf73aaf (2026-08-15).
Data as JSON: /api/errors/3c2a06aa2fc0178a.
Report an issue: GitHub.