{"record":{"id":"80b58d3cc53b4032","repo":"zitadel/zitadel","slug":"unable-to-set-logger-w-80b58d","errorCode":null,"errorMessage":"unable to set logger: %w","messagePattern":"unable to set logger: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/ready/config.go","lineNumber":47,"sourceCode":"\t\tviper.DecodeHook(mapstructure.ComposeDecodeHookFunc(\n\t\t\thook.Base64ToBytesHookFunc(),\n\t\t\tmapstructure.StringToTimeDurationHookFunc(),\n\t\t\tmapstructure.StringToTimeHookFunc(time.RFC3339),\n\t\t\tmapstructure.StringToSliceHookFunc(\",\"),\n\t\t\thook.EnumHookFunc(internal_authz.MemberTypeString),\n\t\t\tmapstructure.TextUnmarshallerHookFunc(),\n\t\t)),\n\t)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"unable to read default config: %w\", err)\n\t}\n\t// Force-disable metrics and tracing for ready command\n\tconfig.Instrumentation.Metric.Exporter.Type = instrumentation.ExporterTypeNone\n\tconfig.Instrumentation.Trace.Exporter.Type = instrumentation.ExporterTypeNone\n\t// Legacy logger\n\terr = config.Log.SetLogger()\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"unable to set logger: %w\", err)\n\t}\n\n\tshutdown, err := instrumentation.Start(cmd.Context(), config.Instrumentation)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"unable to start instrumentation: %w\", err)\n\t}\n\tcmd.SetContext(logging.NewCtx(cmd.Context(), logging.StreamRuntime))\n\n\treturn config, shutdown, nil\n}\n","sourceCodeStart":29,"sourceCodeEnd":58,"githubUrl":"https://github.com/zitadel/zitadel/blob/13948f2bcd6f257794dbd6d342c2ac30bc88fe54/cmd/ready/config.go#L29-L58","documentation":"cmd/ready's newConfig wraps any failure from config.Log.SetLogger() with \"unable to set logger: %w\". The ready command needs a working logger before it runs health probes; if the legacy logger cannot be constructed from the config (logging config invalid, sink not writable, formatter misconfigured), startup aborts with this wrapper. The underlying cause is always in the wrapped error.","triggerScenarios":"Running `zitadel ready` with a Log config section that SetLogger() rejects — e.g. an invalid log level, unsupported formatter in LogSlog/legacy config, or a log destination that cannot be opened.","commonSituations":"Misquoted or invalid YAML in the Log section of config.yaml; ZITADEL_LOG_* env vars set to invalid values; running ready in a container where the configured log file path is not writable.","solutions":["Read the wrapped %w cause in the error output; fix the specific logger config problem it names.","Validate the Log section in config.yaml / ZITADEL_LOG* env vars (valid level, formatter, sink).","Run with default logging (remove custom Log overrides) to confirm the custom config is the culprit."],"exampleFix":"// before (config.yaml)\nLog:\n  Level: verbosedebug\n// after\nLog:\n  Level: debug","handlingStrategy":"validation","validationCode":"cfg, _ := readConfig()\nif cfg.Log.Level == \"\" || !isValidLogLevel(cfg.Log.Level) {\n    return fmt.Errorf(\"invalid log level %q\", cfg.Log.Level)\n}","typeGuard":null,"tryCatchPattern":"if err := config.Log.SetLogger(); err != nil {\n    return fmt.Errorf(\"unable to set logger: %w\", err)\n}","preventionTips":["Keep Log config minimal; only override level/formatter when needed.","Validate config.yaml with `zitadel setup --config` dry runs before automating ready.","Pin valid values for ZITADEL_LOG_LEVEL / ZITADEL_LOG_FORMATTER in your deployment env."],"tags":["logging","config","startup","cli"],"backgroundTag":"invalid-config-value","analyzedSha":"13948f2bcd6f257794dbd6d342c2ac30bc88fe54","analyzedAt":"2026-09-06T10:16:19.814Z","contentChangedAt":"2026-09-06T10:16:19.814Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}