labstack/echo · error
echo key-auth middleware requires a validator function
Error message
echo key-auth middleware requires a validator function
What it means
Returned by KeyAuthConfig.ToMiddleware when config.Validator is nil. The Validator is the only way the middleware can decide whether an extracted key is valid, so omitting it makes the middleware meaningless. The Validator is also where constant-time comparison must happen to prevent timing attacks (see KeyAuthValidator docs).
Source
Thrown at middleware/key_auth.go:146
// KeyAuthWithConfig returns an KeyAuth middleware or panics if configuration is invalid.
//
// For first valid key it calls the next handler.
// For invalid key, it sends "401 - Unauthorized" response.
// For missing key, it sends "400 - Bad Request" response.
func KeyAuthWithConfig(config KeyAuthConfig) echo.MiddlewareFunc {
return toMiddlewareOrPanic(config)
}
// ToMiddleware converts KeyAuthConfig to middleware or returns an error for invalid configuration
func (config KeyAuthConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
if config.Skipper == nil {
config.Skipper = DefaultKeyAuthConfig.Skipper
}
if config.KeyLookup == "" {
config.KeyLookup = DefaultKeyAuthConfig.KeyLookup
}
if config.Validator == nil {
return nil, errors.New("echo key-auth middleware requires a validator function")
}
limit := cmp.Or(config.AllowedCheckLimit, 1)
extractors, cErr := createExtractors(config.KeyLookup, limit)
if cErr != nil {
return nil, fmt.Errorf("echo key-auth middleware could not create key extractor: %w", cErr)
}
if len(extractors) == 0 {
return nil, errors.New("echo key-auth middleware could not create extractors from KeyLookup string")
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c *echo.Context) error {
if config.Skipper(c) {
return next(c)
}
View on GitHub (pinned to 05489dc173)
Solutions
- Set config.Validator to a KeyAuthValidator that checks the key using crypto/subtle.ConstantTimeCompare.
- Prefer the shorthand KeyAuth(func(c *echo.Context, key string, _ middleware.ExtractorSource) (bool, error) {...}) when you only need a validator.
- Wire the validator from your key store (DB, secret manager) at startup so it is never nil.
- Use config.ToMiddleware() to surface this as a returned error instead of a startup panic.
Example fix
// before
m := middleware.KeyAuthWithConfig(middleware.KeyAuthConfig{
KeyLookup: "header:X-Api-Key",
})
// after
m := middleware.KeyAuthWithConfig(middleware.KeyAuthConfig{
KeyLookup: "header:X-Api-Key",
Validator: func(c *echo.Context, key string, _ middleware.ExtractorSource) (bool, error) {
return subtle.ConstantTimeCompare([]byte(key), []byte(validKey)) == 1, nil
},
}) Defensive patterns
Strategy: validation
Validate before calling
func keyAuthMiddleware(lookup string, v middleware.KeyAuthValidator) (echo.MiddlewareFunc, error) {
cfg := middleware.KeyAuthConfig{KeyLookup: lookup, Validator: v}
if cfg.Validator == nil {
return nil, errors.New("KeyAuth requires a Validator")
}
return cfg.ToMiddleware()
} Prevention
- Always set Validator (use crypto/subtle.ConstantTimeCompare inside it to prevent timing attacks).
- Prefer the KeyAuth(fn) shorthand which makes the validator a required parameter.
- Use cfg.ToMiddleware() so a missing validator returns an error instead of panicking.
When it happens
Trigger: Calling KeyAuthWithConfig(KeyAuthConfig{KeyLookup: "header:X-Api-Key"}) without setting Validator, or building a config struct and forgetting the Validator field.
Common situations: Developer uses the WithConfig form to customize KeyLookup but forgets Validator; or copies a config and deletes the validator while refactoring. The shorthand KeyAuth(fn) makes this hard to hit because the function is a required argument.
Related errors
- at least one AllowOrigins is required or UnsafeAllowOriginFu
- echo key-auth middleware could not create extractors from Ke
- timeout must be set
- * as allowed origin and AllowCredentials=true is insecure an
- echo proxy middleware requires balancer
AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04).
Data as JSON: /data/errors/086543bb47d0b900.json.
Report an issue: GitHub.