labstack/echo · critical

panic: err from config.ToMiddleware()

Error message

panic: err from config.ToMiddleware()

What it means

Panicked by toMiddlewareOrPanic (middleware.go:94) when config.ToMiddleware() returns a non-nil error. This helper is used by all *WithConfig constructors (KeyAuthWithConfig, StaticWithConfig, CORSConfig, etc.) in v4. The panic surfaces configuration errors that ToMiddleware detects (missing validator, bad template, invalid origins, etc.).

Solutions

  1. Call config.ToMiddleware() directly and handle the error instead of using *WithConfig when you want non-panic behavior.
  2. Inspect the panicked error to identify which config field is invalid.
  3. Validate all config fields (Validator set, templates parse, origins well-formed) before constructing the middleware.
  4. Wrap middleware setup in a function returning error for testability.

Example fix

// before: panics on bad config at startup
mw := middleware.KeyAuthWithConfig(middleware.KeyAuthConfig{}) // missing Validator
// after: construct explicitly and handle error
mw, err := middleware.KeyAuthConfig{}.ToMiddleware()
if err != nil {
    log.Fatal(err)
}
e.Use(mw)
Defensive patterns

Strategy: validation

Validate before calling

// Use ToMiddleware() directly to get an error instead of a panic.
mw, err := cfg.ToMiddleware()
if err != nil {
    return fmt.Errorf("middleware config invalid: %w", err)
}
e.Use(mw)

Try / catch

// Wrap *WithConfig construction to capture panics during setup.
func buildMiddleware(cfg echo.MiddlewareConfigurator) (mw echo.MiddlewareFunc, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("ToMiddleware panic: %v", r)
        }
    }()
    mw = middleware.ToMiddlewareOrPanic(cfg) // or the package-level WithConfig
    return mw, nil
}

Prevention

When it happens

Trigger: Calling any middleware.XxxWithConfig(cfg) where cfg violates the middleware's invariants: KeyAuth without a Validator, CORS with malformed AllowOrigins, Static with a bad template or Root, etc. The panic propagates the specific ToMiddleware error.

Common situations: Forgetting a required config field (e.g. KeyAuth Validator); supplying invalid strings parsed at construction; loading config from external sources without validation; running newly added middleware with incomplete config.

Related errors


AI-assisted analysis of labstack/echo@05489dc173 (2026-08-04). Data as JSON: /api/errors/876c0bd1646a118b. Report an issue: GitHub.

Appendix: source

Thrown at middleware/middleware.go:94

				return err
			}
			req.URL = url

			return nil // rewrite only once
		}
	}
	return nil
}

// DefaultSkipper returns false which processes the middleware.
func DefaultSkipper(c *echo.Context) bool {
	return false
}

func toMiddlewareOrPanic(config echo.MiddlewareConfigurator) echo.MiddlewareFunc {
	mw, err := config.ToMiddleware()
	if err != nil {
		panic(err)
	}
	return mw
}

View on GitHub (pinned to 05489dc173)