crowdsecurity/crowdsec · error
unable to compile whitelist expression '%s' : %v
Error message
unable to compile whitelist expression '%s' : %v
What it means
CompileWLs compiles each `whitelist: expression:` entry with the expr language; a syntactically or semantically invalid expression (unknown field, type error) is reported as "unable to compile whitelist expression". Expressions run against the event (evt) at parse time, so they must compile against the evt/pipeline.Event environment.
Source
Thrown at pkg/parser/whitelist.go:137
n.Whitelist.B_Ips = append(n.Whitelist.B_Ips, addr)
n.Logger.Debugf("adding ip %s to whitelists", addr)
}
for _, v := range n.Whitelist.Cidrs {
tnet, err := netip.ParsePrefix(v)
if err != nil {
return false, fmt.Errorf("parsing whitelist: %w", err)
}
n.Whitelist.B_Cidrs = append(n.Whitelist.B_Cidrs, tnet)
n.Logger.Debugf("adding cidr %s to whitelists", tnet)
}
for _, filter := range n.Whitelist.Exprs {
var err error
expression := &ExprWhitelist{}
expression.Filter, err = expr.Compile(filter, exprhelpers.GetExprOptions(map[string]any{"evt": &pipeline.Event{}})...)
if err != nil {
return false, fmt.Errorf("unable to compile whitelist expression '%s' : %v", filter, err)
}
n.Whitelist.B_Exprs = append(n.Whitelist.B_Exprs, expression)
n.Logger.Debugf("adding expression %s to whitelists", filter)
}
return n.ContainsWLs(), nil
}
func (n *Node) bumpWhitelistMetric(counter *prometheus.CounterVec, p *pipeline.Event) {
// better safe than sorry
acquisType := p.Line.Labels["type"]
if acquisType == "" {
acquisType = "unknown"
}
labels := prometheus.Labels{
"source": p.Line.Src,
"type": p.Line.Module,
"name": n.Name,View on GitHub (pinned to 909b515798)
Solutions
- Fix the expression per the expr error (line/column are included in the wrapped %v); test it with `cscli explain` or against a sample event
- Verify the referenced fields exist in the parsed event (run crowdsec with parser debug to dump evt.Parsed)
- Escape strings with single quotes and check bracket/paren balance
- After crowdsec upgrades, re-validate custom whitelist expressions against the current pipeline.Event schema
Example fix
// before expression: evt.Parsed.source_ip == "1.2.3.4" && evt // after expression: evt.Parsed.source_ip == '1.2.3.4'
Defensive patterns
Strategy: validation
Validate before calling
import "github.com/expr-lang/expr"
func validWLExprs(exprs []string) error {
for _, e := range exprs {
if _, err := expr.Compile(e); err != nil {
return fmt.Errorf("whitelist expr %q invalid: %w", e, err)
}
}
return nil
} Try / catch
ok, err := node.CompileWLs()
if err != nil {
if strings.Contains(err.Error(), "unable to compile whitelist expression") {
log.Fatalf("fix whitelist expression named in error: %v", err)
}
return err
} Prevention
- Test expressions with `cscli explain` on real events before deploying
- Only reference fields confirmed present in evt.Parsed/evt.Enriched
- Use single quotes for strings and check expr docs for type rules
- Re-validate expressions after crowdsec upgrades
When it happens
Trigger: expr.Compile(filter, ...) failing during CompileWLs — typo in evt fields, unbalanced brackets, comparing incompatible types, or referencing an undeclared variable in a whitelist `expression:` entry.
Common situations: Copy-pasted expression referencing fields the parsed event never sets (e.g. evt.Parsed.src_user); expr syntax errors like missing quotes; upgrading crowdsec changes available evt fields, breaking an old custom expression.
Related errors
- failed to compile node in '%s' : %s
- parsing whitelist: %w
- path must start with /
- on_challenge hooks are only valid in-band, not under outofba
- empty cti key
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/b592014368a97998.
Report an issue: GitHub.