thanos-io/thanos · error
level field is empty
Error message
level field is empty
What it means
checkOptionsConfigEmpty validates gRPC logging interceptor options: a config is fully empty only if no level is set AND neither LogStart nor LogEnd is requested. If a log decision (LogStart or LogEnd) is requested but the level field is empty, the configuration is contradictory and this error is raised.
Solutions
- Set the 'level' field in the logging config (INFO/DEBUG/ERROR/WARNING).
- If no logging is wanted, remove the logStart/logEnd decisions instead of leaving level empty.
- Validate the YAML block before applying it with NewGRPCOption.
Example fix
// before
grpc:
- logStart: true
// after
grpc:
- level: INFO
logStart: true Defensive patterns
Strategy: validation
Validate before calling
if (decision.LogStart || decision.LogEnd) && level == "" {
return fmt.Errorf("level must be set when logStart/logEnd is enabled")
} Try / catch
opt, err := logging.NewGRPCOption(cfg)
if err != nil { return fmt.Errorf("invalid gRPC logging config: %w", err) } Prevention
- Always pair log decisions with a level in YAML
- Render logging config from a schema-validated template
- Test config load in CI before deploy
When it happens
Trigger: Creating gRPC logging options from YAML where a decision like logStart: true or logEnd: true is set but the 'level' field is omitted or empty string.
Common situations: Partially filled logging config blocks in the gRPC server options YAML; users setting log decisions under a different config key than 'level'.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- log decision combination is not supported
- level field in YAML file is empty
- the format of level is invalid. Expected…
- log start call is not supported
- building gRPC client
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/f581d7a5ae579e70.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/logging/grpc.go:33
// NewRequestConfig parses the string into a req logging config structure.
// Raise an error if unmarshalling is not possible, or values are not valid.
func NewRequestConfig(configYAML []byte) (*RequestConfig, error) {
reqLogConfig := &RequestConfig{}
if err := yaml.UnmarshalStrict(configYAML, reqLogConfig); err != nil {
return nil, err
}
return reqLogConfig, nil
}
// checkOptionsConfigEmpty checks if the OptionsConfig struct is empty and valid.
// If invalid combination is present, return an error.
func checkOptionsConfigEmpty(optcfg OptionsConfig) (bool, error) {
if optcfg.Level == "" && !optcfg.Decision.LogEnd && !optcfg.Decision.LogStart {
return true, nil
}
if optcfg.Level == "" && (optcfg.Decision.LogStart || optcfg.Decision.LogEnd) {
return false, fmt.Errorf("level field is empty")
}
return false, nil
}
// fillGlobalOptionConfig configures all the method to have global config for logging.
func fillGlobalOptionConfig(reqLogConfig *RequestConfig, isgRPC bool) (string, bool, bool, error) {
globalLevel := "ERROR"
globalStart, globalEnd := false, false
globalOptionConfig := reqLogConfig.Options
isEmpty, err := checkOptionsConfigEmpty(globalOptionConfig)
// If the decision for logging is enabled with empty level field.
if err != nil {
return "", false, false, err
}
if !isEmpty {
globalLevel = globalOptionConfig.LevelView on GitHub (pinned to 35b8b99117)