labstack/echo · error
at least one AllowOrigins is required or UnsafeAllowOriginFu
Error message
at least one AllowOrigins is required or UnsafeAllowOriginFunc must be provided
What it means
Returned by CORSConfig.ToMiddleware when both AllowOrigins is empty and UnsafeAllowOriginFunc is nil. CORS requires at least one allowed origin (or a custom validator) to populate the Access-Control-Allow-Origin header; with neither, the middleware cannot decide whom to trust. Surfaced as a panic via CORSWithConfig / CORS().
Source
Thrown at middleware/cors.go:174
hasCustomAllowMethods := true
if len(config.AllowMethods) == 0 {
hasCustomAllowMethods = false
config.AllowMethods = []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete}
}
allowMethods := strings.Join(config.AllowMethods, ",")
allowHeaders := strings.Join(config.AllowHeaders, ",")
exposeHeaders := strings.Join(config.ExposeHeaders, ",")
maxAge := "0"
if config.MaxAge > 0 {
maxAge = strconv.Itoa(config.MaxAge)
}
allowOriginFunc := config.UnsafeAllowOriginFunc
if config.UnsafeAllowOriginFunc == nil {
if len(config.AllowOrigins) == 0 {
return nil, errors.New("at least one AllowOrigins is required or UnsafeAllowOriginFunc must be provided")
}
allowOriginFunc = config.defaultAllowOriginFunc
for _, origin := range config.AllowOrigins {
if origin == "*" {
if config.AllowCredentials {
return nil, fmt.Errorf("* as allowed origin and AllowCredentials=true is insecure and not allowed. Use custom UnsafeAllowOriginFunc")
}
allowOriginFunc = config.starAllowOriginFunc
break
}
if err := validateOrigin(origin, "allow origin"); err != nil {
return nil, err
}
}
config.AllowOrigins = append([]string(nil), config.AllowOrigins...)
}
return func(next echo.HandlerFunc) echo.HandlerFunc {View on GitHub (pinned to 05489dc173)
Solutions
- Pass at least one origin: CORS("https://app.example.com") or set AllowOrigins in the config.
- If origins must be computed dynamically, set UnsafeAllowOriginFunc instead (it overrides AllowOrigins).
- When loading origins from config/env, fail fast at boot if the resulting slice is empty rather than passing it to the middleware.
- Use config.ToMiddleware() to receive the error instead of a panic during wiring.
Example fix
// before
m := middleware.CORSWithConfig(middleware.CORSConfig{
AllowMethods: []string{http.MethodGet, http.MethodPost},
})
// after
m := middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"https://app.example.com"},
AllowMethods: []string{http.MethodGet, http.MethodPost},
}) Defensive patterns
Strategy: validation
Validate before calling
func corsMiddleware(origins []string) (echo.MiddlewareFunc, error) {
cfg := middleware.CORSConfig{AllowOrigins: origins}
if len(cfg.AllowOrigins) == 0 && cfg.UnsafeAllowOriginFunc == nil {
return nil, errors.New("CORS requires at least one AllowOrigins entry or UnsafeAllowOriginFunc")
}
return cfg.ToMiddleware()
} Prevention
- Always pass at least one origin to CORS(...) or set AllowOrigins in CORSWithConfig.
- When origins come from env/config, fail fast at boot if the slice is empty.
- Use cfg.ToMiddleware() in wiring code to receive the error instead of a panic.
When it happens
Trigger: Calling CORSWithConfig(CORSConfig{}) with no AllowOrigins and no UnsafeAllowOriginFunc, or calling CORS() with zero variadic arguments (allowOrigins...string expands to nil).
Common situations: Developer switches from CORS("https://app.example.com") to CORSWithConfig to set AllowMethods/AllowHeaders and forgets to carry AllowOrigins over; or an empty env var feeds the origin list producing an empty slice.
Related errors
- * as allowed origin and AllowCredentials=true is insecure an
- echo key-auth middleware requires a validator function
- timeout must be set
- echo key-auth middleware could not create extractors from Ke
- echo proxy middleware requires balancer
AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04).
Data as JSON: /data/errors/5deceee6621d56e4.json.
Report an issue: GitHub.