zitadel/zitadel · error

system defaults config invalid: %w

Error message

system defaults config invalid: %w

What it means

NewConfig validates the SystemDefaults section of the ZITADEL startup configuration. If SystemDefaults.Validate() fails, the error is wrapped as 'system defaults config invalid' and joined with the shutdown error from terminating the command context. It indicates the built-in/default values derived from config (typically from defaults.yaml plus overrides) are internally inconsistent or incomplete.

Source

Thrown at cmd/start/config.go:136

	// Legacy logger
	err = config.Log.SetLogger()
	if err != nil {
		err = errors.Join(err, shutdown(cmd.Context()))
		return nil, nil, fmt.Errorf("unable to set logger: %w", err)
	}

	id.Configure(config.Machine)

	var actionsDenylist []denylist.AddressChecker
	if config.Actions != nil {
		actionsDenylist = config.Actions.HTTP.DenyList
	}
	config.HTTPClient.MergeDeprecatedDenylists(actionsDenylist, config.Executions.DenyList)

	err = config.SystemDefaults.Validate()
	if err != nil {
		err = errors.Join(err, shutdown(cmd.Context()))
		return nil, nil, fmt.Errorf("system defaults config invalid: %w", err)
	}
	// Copy the global role permissions mappings to the instance until we allow instance-level configuration over the API.
	config.DefaultInstance.RolePermissionMappings = config.InternalAuthZ.RolePermissionMappings

	return config, shutdown, nil
}

func readConfig(v *viper.Viper) (*Config, error) {
	config := new(Config)

	err := v.Unmarshal(config,
		viper.DecodeHook(mapstructure.ComposeDecodeHookFunc(
			hooks.SliceTypeStringDecode[*domain.CustomMessageText],
			hooks.SliceTypeStringDecode[authz.RoleMapping],
			hooks.MapTypeStringDecode[string, *authz.SystemAPIUser],
			hooks.MapHTTPHeaderStringDecode,
			database.DecodeHook(false),
			actions.HTTPConfigDecodeHook,

View on GitHub (pinned to 13948f2bcd)

Solutions

  1. Check the wrapped cause (%w) in the log for the exact failing field in SystemDefaults.Validate
  2. Restore/merge your config with the defaults.yaml shipped for your ZITADEL version so all SystemDefaults fields are present
  3. Fix the specific invalid value (e.g. duration syntax, empty field) in your config file or offending ZITADEL_* env var
  4. Run with a pristine defaults.yaml to confirm the stock config validates, then reapply overrides incrementally

Example fix

// before (config override via env)
ZITADEL_SYSTEMDEFAULTS_SECRETGENERATORS_OTP_MINFREQUENCY=notanumber
// after
ZITADEL_SYSTEMDEFAULTS_SECRETGENERATORS_OTP_MINFREQUENCY=1000000
Defensive patterns

Strategy: validation

Validate before calling

// before start: sanity-check SystemDefaults via config load
_, shutdown, err := cmd.NewConfig(ctx)
if err != nil { log.Fatalf("config invalid: %v", err) }
_ = shutdown

Try / catch

// Go: inspect wrapped error
if err != nil {
    var cfgErr error
    if errors.As(err, &cfgErr) { log.Printf("cause: %v", cfgErr) }
    os.Exit(1)
}

Prevention

When it happens

Trigger: Calling NewConfig (via `zitadel start`/`start-from-init`) when config.SystemDefaults contains invalid values — e.g. malformed durations, empty required fields, or invalid secret generator/language settings after merging defaults.yaml, config file, and env overrides.

Common situations: Hand-edited or partially overridden defaults.yaml; environment variables that override SystemDefaults fields with invalid formats; upgrading ZITADEL and reusing an old config missing newly required SystemDefaults fields.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of zitadel/zitadel@13948f2bcd (2026-09-06). Data as JSON: /api/errors/0a9ff85f3f8a8cf3. Report an issue: GitHub.