jaegertracing/jaeger · error
failed to unmarshal configuration: %w
Error message
failed to unmarshal configuration: %w
What it means
LoadConfigFromViper unmarshals the entire Viper state into the remote-storage Config struct (GRPC server, tenancy, storage backends). Viper's Unmarshal relies on mapstructure; when the YAML/env values cannot be decoded into the target fields (wrong types, unknown keys with strict decoding, bad nested structures) this error wraps and re-raises the decode failure.
Source
Thrown at cmd/remote-storage/app/config.go:33
"github.com/jaegertracing/jaeger/internal/tenancy"
)
// Config represents the configuration for remote-storage service.
type Config struct {
GRPC configgrpc.ServerConfig `mapstructure:"grpc"`
Tenancy tenancy.Options `mapstructure:"multi_tenancy"`
// This configuration is the same as of the main `jaeger` binary,
// but only one backend should be defined.
Storage storageconfig.Config `mapstructure:"storage"`
}
// LoadConfigFromViper loads the configuration from Viper.
func LoadConfigFromViper(v *viper.Viper) (*Config, error) {
cfg := &Config{}
// Unmarshal the entire configuration
if err := v.Unmarshal(cfg); err != nil {
return nil, fmt.Errorf("failed to unmarshal configuration: %w", err)
}
// Validate storage configuration
if err := cfg.Validate(); err != nil {
return nil, fmt.Errorf("invalid configuration: %w", err)
}
return cfg, nil
}
// Validate validates the configuration.
func (c *Config) Validate() error {
// Validate storage configuration
if err := c.Storage.Validate(); err != nil {
return err
}
// Ensure only one backend is defined for remote-storageView on GitHub (pinned to 806f444784)
Solutions
- Read the wrapped mapstructure error — it names the exact field and expected type
- Fix the YAML/env value type to match the Config struct (e.g. quote-free ints, correct nesting under grpc/multi_tenancy/storage)
- Validate the config file against the current Jaeger version's remote-storage schema; migrate old keys
- Start from the documented sample remote-storage config and re-apply your overrides
Example fix
# before
storage:
trace_backends: "cassandra" # string, must be a map
# after
storage:
trace_backends:
cassandra:
cassandra:
servers: [cassandra:9042] Defensive patterns
Strategy: validation
Validate before calling
func validateRemoteStorageKeys(v *viper.Viper) error {
for _, key := range []string{"grpc", "storage"} {
if v.Get(key) == nil { return fmt.Errorf("missing required section %q", key) }
}
if _, ok := v.Get("storage.trace_backends").(map[string]any); !ok {
return fmt.Errorf("storage.trace_backends must be a map of backend name -> config")
}
return nil
} Try / catch
cfg, err := app.LoadConfigFromViper(v)
if err != nil {
var decodeErr mapstructure.Error
if errors.As(err, &decodeErr) {
for _, e := range decodeErr.Errors { fmt.Fprintln(os.Stderr, "config: ", e) }
}
return fmt.Errorf("loading remote-storage config: %w", err)
} Prevention
- Lint remote-storage YAML against the current Jaeger schema
- Match value types to struct fields (ints unquoted, maps not strings)
- Migrate configs when upgrading Jaeger; the storage config layout changes between versions
- Test config loading in CI with a LoadConfigFromViper smoke test
When it happens
Trigger: Calling LoadConfigFromViper with a viper instance whose settings do not match the Config schema — e.g. grpc port given as a string where a struct field is expected, multi_tenancy shaped incorrectly, or a storage backend field of the wrong type.
Common situations: Typo'd or misindented remote-storage config file; passing raw env vars of string type into numeric/struct fields; upgrading Jaeger where the storage config schema changed (single-backend `storage` layout) while using an old config; supplying full `jaeger` multi-backend storage config to the remote-storage binary.
Related errors
- invalid configuration: %w
- remote-storage only supports a single storage backend, but %
- server with TLS enabled can not use same host ports for gRPC
- the structured query filter is disabled
- archive span storage was not configured
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/f7705487beb5d514.
Report an issue: GitHub.