crowdsecurity/crowdsec · error

on_route_not_found: %w

Error message

on_route_not_found: %w

What it means

LoadSchema validates the OnRouteNotFound policy option before loading the schema. A Policy is only valid when it equals "drop" or "ignore"; anything else (empty string, typo, wrong casing) fails validation and the error is wrapped as "on_route_not_found: ...".

Source

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

		}

		return nil
	}
}

func (rv *RequestValidator) LoadSchema(ref string, schema string, opts *SchemaOptions) error {
	if ref == "" {
		return errors.New("ref cannot be empty")
	}
	rv.logger.Debugf("loading schema for ref %s", ref)

	if _, exists := rv.loaders[ref]; exists {
		return fmt.Errorf("attempting to load a new schema for existing ref %s", ref)
	}

	options := opts.withDefaults()
	if err := options.OnRouteNotFound.validate(); err != nil {
		return fmt.Errorf("on_route_not_found: %w", err)
	}
	if err := options.OnMethodNotAllowed.validate(); err != nil {
		return fmt.Errorf("on_method_not_allowed: %w", err)
	}
	if err := options.OnUnsupportedSecurityScheme.validate(); err != nil {
		return fmt.Errorf("on_unsupported_security_scheme: %w", err)
	}

	loader := openapi3.NewLoader()
	rv.loaders[ref] = loader

	doc, err := loader.LoadFromData([]byte(schema))
	if err != nil {
		return fmt.Errorf("failed to load schema %s: %w", ref, err)
	}

	// Is it a valid OpenAPI schema?
	// TODO: look into opts, should we expose some of them to the user ?

View on GitHub (pinned to 909b515798)

Solutions

  1. Set on_route_not_found to exactly "drop" or "ignore" in the appsec config.
  2. Check casing — the values are lowercase and case-sensitive.
  3. If the field was explicitly set to "", remove the key so defaults apply.
  4. Validate config values before constructing SchemaOptions in embedding code.

Example fix

// before
opts.OnRouteNotFound = api_validation.Policy("block")

// after
opts.OnRouteNotFound = api_validation.PolicyDrop // "drop"
Defensive patterns

Strategy: validation

Validate before calling

func validPolicy(p api_validation.Policy) bool {
    return p == api_validation.PolicyDrop || p == api_validation.PolicyIgnore
}
// call before LoadSchema
if !validPolicy(opts.OnRouteNotFound) { return fmt.Errorf("bad on_route_not_found: %q", opts.OnRouteNotFound) }

Type guard

func isPolicy(s string) bool { return s == "drop" || s == "ignore" }

Try / catch

if err := rv.LoadSchema(ref, schema, opts); err != nil {
    var pe *fmt.WrapError // or inspect the wrapped text
    if strings.Contains(err.Error(), "on_route_not_found:") {
        log.Errorf("fix on_route_not_found in config (drop|ignore): %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling LoadSchema with SchemaOptions whose OnRouteNotFound is set to an invalid string, e.g. Policy("block"), "", or "Drop" (case-sensitive), typically from a YAML appsec config mapping on_route_not_found to an unsupported value.

Common situations: Typos in the appsec config YAML ("droped", "bloc"); wrong casing after hand-editing; a config key copied from an older/other product that used different policy names; passing a zero-value struct with an explicitly empty policy.

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/7dc0627c519d1876. Report an issue: GitHub.