{"record":{"id":"8d68e1d721219b1c","repo":"jaegertracing/jaeger","slug":"invalid-configuration-w","errorCode":null,"errorMessage":"invalid configuration: %w","messagePattern":"invalid configuration: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/remote-storage/app/config.go","lineNumber":38,"sourceCode":"\tGRPC    configgrpc.ServerConfig `mapstructure:\"grpc\"`\n\tTenancy tenancy.Options         `mapstructure:\"multi_tenancy\"`\n\t// This configuration is the same as of the main `jaeger` binary,\n\t// but only one backend should be defined.\n\tStorage storageconfig.Config `mapstructure:\"storage\"`\n}\n\n// LoadConfigFromViper loads the configuration from Viper.\nfunc LoadConfigFromViper(v *viper.Viper) (*Config, error) {\n\tcfg := &Config{}\n\n\t// Unmarshal the entire configuration\n\tif err := v.Unmarshal(cfg); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal configuration: %w\", err)\n\t}\n\n\t// Validate storage configuration\n\tif err := cfg.Validate(); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid configuration: %w\", err)\n\t}\n\n\treturn cfg, nil\n}\n\n// Validate validates the configuration.\nfunc (c *Config) Validate() error {\n\t// Validate storage configuration\n\tif err := c.Storage.Validate(); err != nil {\n\t\treturn err\n\t}\n\n\t// Ensure only one backend is defined for remote-storage\n\tif len(c.Storage.TraceBackends) > 1 {\n\t\treturn fmt.Errorf(\"remote-storage only supports a single storage backend, but %d were configured\", len(c.Storage.TraceBackends))\n\t}\n\n\treturn nil","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/remote-storage/app/config.go#L20-L56","documentation":"After a successful Viper unmarshal, LoadConfigFromViper calls Config.Validate() and wraps any validation failure as `invalid configuration: %w`. This means the config parsed but is semantically rejected — either by storageconfig.Config.Validate() (backend-specific constraints) or because more than one trace backend was configured for the remote-storage service.","triggerScenarios":"Calling LoadConfigFromViper with structurally valid YAML that fails cfg.Validate(): e.g. two entries under storage.trace_backends, or a backend entry violating the storage config's own validation rules (missing required fields for the declared backend type).","commonSituations":"Copying the main `jaeger` binary's multi-backend storage config into remote-storage; defining both a memory and a cassandra backend; leaving a backend entry empty/missing its type-specific configuration block.","solutions":["Read the wrapped inner error to see which validation rule failed","Ensure at most one backend is defined under storage.trace_backends (remote-storage is single-backend)","Ensure the single backend entry includes its required type-specific block (e.g. `memory:` or `cassandra:`)","Run with the DefaultConfig-style structure as a reference and adjust field-by-field"],"exampleFix":"// before\nstorage:\n  trace_backends:\n    memory: {memory: {max_traces: 1000000}}\n    cassandra: {cassandra: {servers: [cassandra:9042]}}\n// after\nstorage:\n  trace_backends:\n    cassandra: {cassandra: {servers: [cassandra:9042]}}","handlingStrategy":"validation","validationCode":"backends := v.GetStringMap(\"storage.trace_backends\")\nif len(backends) > 1 {\n    return fmt.Errorf(\"remote-storage supports one backend, got %d\", len(backends))\n}\nif len(backends) == 1 {\n    for name, cfgAny := range backends {\n        m, ok := cfgAny.(map[string]any)\n        if !ok || len(m) == 0 {\n            return fmt.Errorf(\"backend %q has empty configuration\", name)\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":"cfg, err := app.LoadConfigFromViper(v)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid configuration\") {\n        // semantic validation failed; inspect wrapped cause for the rule\n        fmt.Fprintf(os.Stderr, \"config rejected: %v\\n\", err)\n        os.Exit(1)\n    }\n    return err\n}","preventionTips":["Never copy the multi-backend `jaeger` storage config into remote-storage","Keep exactly one named backend under storage.trace_backends","Ensure each backend entry has its type-specific block populated","Validate config early at deploy time, not at service start"],"tags":["go","configuration","validation","remote-storage"],"backgroundTag":"invalid-config-value","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}