crowdsecurity/crowdsec · error · ErrInvalidSchemaName

%w: no schema loaded for ref %s

Error message

%w: no schema loaded for ref %s

What it means

ValidateRequest looks up an OpenAPI schema by its ref name in the validator's internal registry before validating an HTTP request. If the ref was never registered via ValidateSchema (or was registered under a different name), the request cannot be validated, so the call fails with the ErrInvalidSchemaName sentinel wrapped with the offending ref. This is a lookup failure on the validator's own state, not a problem with the request itself.

Source

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

	router, err := legacyrouter.NewRouter(doc)
	if err != nil {
		return fmt.Errorf("failed to create router for schema ref %s: %w", ref, err)
	}

	rv.openAPISchemas[ref] = SchemaData{
		Schema:  doc,
		Router:  router,
		Options: options,
	}

	rv.logger.Infof("loaded schema for ref %s", ref)
	return nil
}

func (rv *RequestValidator) ValidateRequest(ctx context.Context, ref string, r *http.Request) error {
	schemaData, exists := rv.openAPISchemas[ref]
	if !exists {
		return fmt.Errorf("%w: no schema loaded for ref %s", ErrInvalidSchemaName, ref)
	}

	rv.logger.Debugf("validating request for ref %s", ref)

	route, pathParam, err := schemaData.Router.FindRoute(r)
	if err != nil {
		// The legacy router returns a fresh *routers.RouteError rather than the
		// exported sentinels, so we branch on Reason instead of errors.Is.
		var routeErr *routers.RouteError
		if errors.As(err, &routeErr) {
			switch routeErr.Reason {
			case routers.ErrPathNotFound.Error():
				if schemaData.Options.OnRouteNotFound == PolicyIgnore {
					rv.logger.Debugf("no matching route for %s %s, ignoring per schema policy", r.Method, r.URL.Path)
					return nil
				}
				return &ValidationError{
					Reason:        "route_not_found",

View on GitHub (pinned to 909b515798)

Solutions

  1. Verify the ref string passed to ValidateRequest exactly matches the ref given to ValidateSchema for a successfully loaded schema
  2. Check earlier startup logs for 'failed to validate schema' or 'failed to create router' errors that prevented the schema from being registered
  3. Load the schema before serving traffic (register all refs during AppsecRuntimeConfig build, not lazily)
  4. Handle the error with errors.Is(err, apivalidation.ErrInvalidSchemaName) to distinguish a config problem from a request-validation problem

Example fix

// before
err := validator.ValidateRequest(ctx, "openapi-prod", req)
// after
if err := validator.ValidateSchema(ctx, "openapi-prod", doc, opts); err != nil {
	return fmt.Errorf("loading schema: %w", err)
}
err := validator.ValidateRequest(ctx, "openapi-prod", req)
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Calling RequestValidator.ValidateRequest(ctx, ref, r) with a ref that was never passed to ValidateSchema, or before ValidateSchema completed; a typo or case mismatch between the ref used at registration and the one used at validation time; validating against a schema whose Load failed earlier so it was never stored in rv.openAPISchemas.

Common situations: AppSec config references an OpenAPI spec name that does not match what was loaded from the hub/local files; the appsec-config loads after the first request arrives; renaming a schema file without updating the ref in the config.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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