labstack/echo · error
missing LogValuesFunc callback function for request logger m
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.
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)
Solutions
- Set LogValuesFunc to a function that writes v to your logger (see the package-level examples for slog/zap/zerolog/logrus).
- If you just want default logging via echo.Context.Logger(), use the parameterless RequestLogger() which wires a default callback.
- 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
- Always set LogValuesFunc when using RequestLoggerWithConfig; it is the only place captured values go.
- If you just want default logging, use the parameterless RequestLogger().
- Copy from the package-level slog/zap/zerolog examples to avoid a no-op callback.
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
- timeout must be set
- at least one AllowOrigins is required or UnsafeAllowOriginFu
- echo key-auth middleware requires a validator function
- 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/fbdc0a38456afbdb.json.
Report an issue: GitHub.