thanos-io/thanos · error
the format of level is invalid. Expected…
Error message
the format of level is invalid. Expected INFO/DEBUG/ERROR/WARNING, got this %v
What it means
validateLevel only accepts the exact uppercase strings INFO, DEBUG, ERROR, or WARNING. Any other non-empty value (including lowercase or unsupported levels like TRACE) fails with this formatted error that echoes the invalid value.
Solutions
- Change the level to one of INFO, DEBUG, ERROR, WARNING (uppercase, exact).
- Uppercase/normalize the value in config management before rendering the YAML.
- Add a pre-check rejecting values outside the allowed set.
Example fix
// before level: info // after level: INFO
Defensive patterns
Strategy: validation
Validate before calling
var validLevels = map[string]bool{"INFO": true, "DEBUG": true, "ERROR": true, "WARNING": true}
if !validLevels[level] { return fmt.Errorf("level %q not one of INFO/DEBUG/ERROR/WARNING", level) } Try / catch
if _, err := logging.NewGRPCOption(cfg); err != nil {
return fmt.Errorf("log level invalid: %w", err)
} Prevention
- Uppercase levels in config templates before rendering
- Normalize (strings.ToUpper) then validate against the allowed set
- Document the exact allowed level strings for users
When it happens
Trigger: Calling NewGRPCOption or NewHTTPOption with level values like 'info', 'debug', 'WARN', 'trace', or any typo in the logging YAML config.
Common situations: Users writing lowercase levels as in other frameworks; copy-pasting TRACE (unsupported here); mixed-case values from environment substitution.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- level field is empty
- log decision combination is not supported
- level field in YAML file is empty
- log start call is not supported
- unexpected downsampling resolution
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/5419da43c0133a11.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/logging/grpc.go:99
if !logStart && logEnd {
return grpc_logging.WithLogOnEvents(grpc_logging.FinishCall), nil
}
if logStart && logEnd {
return grpc_logging.WithLogOnEvents(grpc_logging.StartCall, grpc_logging.FinishCall), nil
}
return nil, fmt.Errorf("log decision combination is not supported")
}
// validateLevel validates the list of level entries.
// Raise an error if empty or log level not in uppercase.
func validateLevel(level string) error {
if level == "" {
return fmt.Errorf("level field in YAML file is empty")
}
if level == "INFO" || level == "DEBUG" || level == "ERROR" || level == "WARNING" {
return nil
}
return fmt.Errorf("the format of level is invalid. Expected INFO/DEBUG/ERROR/WARNING, got this %v", level)
}
func InterceptorLogger(l log.Logger) grpc_logging.Logger {
return grpc_logging.LoggerFunc(func(_ context.Context, lvl grpc_logging.Level, msg string, fields ...any) {
largs := append([]any{"msg", msg}, fields...)
switch lvl {
case grpc_logging.LevelDebug:
_ = level.Debug(l).Log(largs...)
case grpc_logging.LevelInfo:
_ = level.Info(l).Log(largs...)
case grpc_logging.LevelWarn:
_ = level.Warn(l).Log(largs...)
case grpc_logging.LevelError:
_ = level.Error(l).Log(largs...)
default:
panic(fmt.Sprintf("unknown level %v", lvl))
}
})View on GitHub (pinned to 35b8b99117)