labstack/echo · error

missing LogValuesFunc callback function for request logger…

Error message

missing LogValuesFunc callback function for request logger middleware

What it means

Returned by RequestLoggerConfig.ToMiddleware when config.LogValuesFunc is nil. This callback is the whole point of RequestLogger — it receives the extracted RequestLoggerValues so you can emit them to your logger (slog, zap, zerolog, etc.). Without it there is nowhere to send the captured data. The parameterless RequestLogger() provides a default callback, so only WithConfig without the field triggers this.

Solutions

  1. Set LogValuesFunc to a function that writes v to your logger (see the package-level examples for slog/zap/zerolog/logrus).
  2. If you just want default logging via echo.Context.Logger(), use the parameterless RequestLogger() which wires a default callback.
  3. Use config.ToMiddleware() to receive the error instead of panicking.

Example fix

// before
m := middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
    LogStatus: true,
    LogURI:    true,
})
// after
m := middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
    LogStatus: true,
    LogURI:    true,
    LogValuesFunc: func(c *echo.Context, v middleware.RequestLoggerValues) error {
        c.Logger().Info("request", "uri", v.URI, "status", v.Status)
        return nil
    },
})
Defensive patterns

Strategy: validation

Validate before calling

func requestLoggerMiddleware(logValues func(*echo.Context, middleware.RequestLoggerValues) error) (echo.MiddlewareFunc, error) {
    cfg := middleware.RequestLoggerConfig{LogStatus: true, LogURI: true, LogValuesFunc: logValues}
    if cfg.LogValuesFunc == nil {
        return nil, errors.New("RequestLogger requires LogValuesFunc")
    }
    return cfg.ToMiddleware()
}

Prevention

When it happens

Trigger: Calling RequestLoggerWithConfig(RequestLoggerConfig{LogStatus: true, LogURI: true}) without setting LogValuesFunc.

Common situations: Developer enables Log* flags but forgets the callback; or assumes the middleware logs to stdout by default like the legacy Logger middleware (it does not — you must supply LogValuesFunc or use RequestLogger()).

Related errors


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

Appendix: source

Thrown at middleware/request_logger.go:256

	mw, err := config.ToMiddleware()
	if err != nil {
		panic(err)
	}
	return mw
}

// ToMiddleware converts RequestLoggerConfig into middleware or returns an error for invalid configuration.
func (config RequestLoggerConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
	if config.Skipper == nil {
		config.Skipper = DefaultSkipper
	}
	now := time.Now
	if config.timeNow != nil {
		now = config.timeNow
	}

	if config.LogValuesFunc == nil {
		return nil, errors.New("missing LogValuesFunc callback function for request logger middleware")
	}

	logHeaders := len(config.LogHeaders) > 0
	headers := append([]string(nil), config.LogHeaders...)
	for i, v := range headers {
		headers[i] = http.CanonicalHeaderKey(v)
	}

	logQueryParams := len(config.LogQueryParams) > 0
	logFormValues := len(config.LogFormValues) > 0

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c *echo.Context) error {
			if config.Skipper(c) {
				return next(c)
			}

			req := c.Request()

View on GitHub (pinned to 05489dc173)