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

  1. 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
  2. Verify the referenced fields exist in the parsed event (run crowdsec with parser debug to dump evt.Parsed)
  3. Escape strings with single quotes and check bracket/paren balance
  4. 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

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


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/b592014368a97998. Report an issue: GitHub.