crowdsecurity/crowdsec · error

unknown body decoder %q

Error message

unknown body decoder %q

What it means

RegisterBodyDecoder maps a content type to a named body decoder in kin-openapi's process-global registry. It first looks the decoder name up in builtinBodyDecoders; if the name is not a registered builtin, it returns this error instead of registering anything.

Source

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

	}

	return &RequestValidator{
		loaders:        make(map[string]*openapi3.Loader),
		openAPISchemas: make(map[string]SchemaData),
		logger:         logger,
	}
}

// RegisterBodyDecoder registers a decoder for the given Content-Type so that
// a loaded OpenAPI schema can declare and validate requests of that type.
// decoderName must be one of the built-in identifiers: "json", "urlencoded",
// "multipart", "yaml", "csv", "plain", "file". Note that this mutates
// kin-openapi's process-global decoder registry — see the note on
// NewRequestValidator.
func (rv *RequestValidator) RegisterBodyDecoder(contentType, decoderName string) error {
	decoder, ok := builtinBodyDecoders[decoderName]
	if !ok {
		return fmt.Errorf("unknown body decoder %q", decoderName)
	}
	openapi3filter.RegisterBodyDecoder(contentType, decoder)
	rv.logger.Debugf("registered body decoder %q for content type %q", decoderName, contentType)
	return nil
}

// warnUnsupportedSecuritySchemes scans a schema's declared security schemes
// once at load time and warns for types the WAF cannot enforce (oauth2,
// openIdConnect). The warning is emitted here so operators learn about the
// gap during schema load rather than via per-request log spam. Behavior at
// request time depends on the OnUnsupportedSecurityScheme policy.
func (rv *RequestValidator) warnUnsupportedSecuritySchemes(ref string, doc *openapi3.T, policy Policy) {
	if doc.Components == nil {
		return
	}
	action := "will fail validation"
	if policy == PolicyIgnore {
		action = "will be ignored (not validated)"

View on GitHub (pinned to 909b515798)

Solutions

  1. Use one of the builtin decoder names (e.g. "multipart", "yaml", "csv", "plain", "file" — see the builtinBodyDecoders map).
  2. Check the decoder name in the config/schema against the supported list for typos.
  3. If a custom decoder is needed, add it to builtinBodyDecoders or register it directly via openapi3filter.RegisterBodyDecoder.

Example fix

// before
rv.RegisterBodyDecoder("application/x-www-form-urlencoded", "urlencoded")
// after
rv.RegisterBodyDecoder("application/x-www-form-urlencoded", "plain")
Defensive patterns

Strategy: validation

Validate before calling

decoders := []string{"multipart", "yaml", "csv", "plain", "file"}; if !slices.Contains(decoders, decoderName) { return fmt.Errorf("decoder %q is not builtin", decoderName) }

Try / catch

if err := rv.RegisterBodyDecoder(ct, name); err != nil { if strings.Contains(err.Error(), "unknown body decoder") { return fmt.Errorf("unsupported decoder %s for %s", name, ct) } return err }

Prevention

When it happens

Trigger: Calling RequestValidator.RegisterBodyDecoder(contentType, decoderName) (directly or via RegisterAPISchemaBodyDecoder) with a decoderName that has no entry in builtinBodyDecoders, at pkg/appsec/api_validation/api_validation.go:185.

Common situations: Typo in a config value like 'jsonn' or 'xml' when one isn't built in; passing a content type string where a decoder name is expected; docs referencing a decoder that was removed.

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