crowdsecurity/crowdsec · error

invalid policy %q (expected %q or %q)

Error message

invalid policy %q (expected %q or %q)

What it means

The api_validation Policy field (used for on_route_not_found / on_method_not_allowed / on_unsupported_security_scheme appsec options) was set to a value other than the two accepted sentinels "drop" or "ignore". This is the config-validation guard in Policy.validate(); the offending value is echoed with the allowed set.

Source

Thrown at pkg/appsec/api_validation/api_validation.go:38

// Policy controls what the validator does when it encounters a condition it
// cannot fully validate (unknown route, method not allowed for a matched
// path, security scheme type the WAF cannot enforce).
type Policy string

const (
	// PolicyDrop treats the condition as a validation failure.
	PolicyDrop Policy = "drop"
	// PolicyIgnore lets the request through as if the condition had passed.
	PolicyIgnore Policy = "ignore"
)

func (p Policy) validate() error {
	switch p {
	case PolicyDrop, PolicyIgnore:
		return nil
	}
	return fmt.Errorf("invalid policy %q (expected %q or %q)", p, PolicyDrop, PolicyIgnore)
}

// SchemaOptions configures per-schema validation behavior. A nil *SchemaOptions
// passed to LoadSchema means "use defaults" (all policies = drop, matching
// pre-option behavior).
type SchemaOptions struct {
	OnRouteNotFound             Policy
	OnMethodNotAllowed          Policy
	OnUnsupportedSecurityScheme Policy
}

func (o *SchemaOptions) withDefaults() SchemaOptions {
	out := SchemaOptions{
		OnRouteNotFound:             PolicyDrop,
		OnMethodNotAllowed:          PolicyDrop,
		OnUnsupportedSecurityScheme: PolicyDrop,
	}
	if o == nil {

View on GitHub (pinned to 909b515798)

Solutions

  1. Set the policy to exactly "drop" or "ignore" (lowercase).
  2. Check the config file/value source for typos or casing issues.
  3. Consult the SchemaOptions docs to confirm the supported policy values.

Example fix

// before
opts.Policy = "block"
// after
opts.Policy = PolicyDrop // or PolicyIgnore
Defensive patterns

Strategy: validation

Validate before calling

policy := "drop"; if policy != "drop" && policy != "ignore" { return fmt.Errorf("policy must be drop or ignore, got %q", policy) }

Type guard

func validPolicy(p string) bool { return p == "drop" || p == "ignore" }

Try / catch

if err := api_validation.LoadSchema(schema, opts); err != nil { if strings.Contains(err.Error(), "invalid policy") { return fmt.Errorf("check appsec config policy value: %w", err) } return err }

Prevention

When it happens

Trigger: Calling LoadSchema/SchemaOptions configuration with a Policy value other than "drop" or "ignore", e.g. a typo like "block" or "deny", triggering validate() at pkg/appsec/api_validation/api_validation.go:38.

Common situations: Typo in appsec API validation config; copying policy names from other WAF tooling (e.g. 'block'); casing mistakes like "Drop".

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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