{"record":{"id":"0878859bb345b9b7","repo":"temporalio/temporal","slug":"unable-to-create-metrics-handler-w","errorCode":null,"errorMessage":"unable to create metrics handler: %w","messagePattern":"unable to create metrics handler: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"temporal/fx.go","lineNumber":213,"sourceCode":"\tstopChan := make(chan any)\n\n\t// ClientFactoryProvider\n\tclientFactoryProvider := so.clientFactoryProvider\n\tif clientFactoryProvider == nil {\n\t\tclientFactoryProvider = client.NewFactoryProvider()\n\t}\n\n\tpersistenceFactoryProvider := so.persistenceFactoryProvider\n\tif persistenceFactoryProvider == nil {\n\t\tpersistenceFactoryProvider = PersistenceFactoryProvider()\n\t}\n\n\t// MetricsHandler\n\tmetricHandler := so.metricHandler\n\tif metricHandler == nil {\n\t\tmetricHandler, err = metrics.MetricsHandlerFromConfig(logger, so.config.Global.Metrics)\n\t\tif err != nil {\n\t\t\treturn serverOptionsProvider{}, fmt.Errorf(\"unable to create metrics handler: %w\", err)\n\t\t}\n\t}\n\n\t// EventLoggerProvider backs structured (\"wide\") events. Select the custom OTEL LoggerProvider\n\t// if injected, else a no-op provider that discards events. A deployment opts in by injecting a\n\t// provider via WithCustomEventLoggerProvider.\n\teventLoggerProvider := so.eventLoggerProvider\n\tif eventLoggerProvider == nil {\n\t\teventLoggerProvider = lognoop.NewLoggerProvider()\n\t}\n\n\t// DynamicConfigClient\n\tdcClient := so.dynamicConfigClient\n\tif dcClient == nil {\n\t\tdcConfig := so.config.DynamicConfigClient\n\t\tif dcConfig != nil {\n\t\t\tdcClient, err = dynamicconfig.NewFileBasedClientWithMetrics(dcConfig, logger, stopChan, metricHandler)\n\t\t\tif err != nil {","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/temporal/fx.go#L195-L231","documentation":"During temporal server (fx) dependency injection, ServerOptionsProvider builds a metrics handler from config.Global.Metrics via metrics.MetricsHandlerFromConfig when no custom handler is injected. Any configuration or initialization failure is wrapped as 'unable to create metrics handler', aborting server startup.","triggerScenarios":"Invalid metrics config section (bad prometheus listen address, unknown exporter type, malformed tags/exclusions), or MetricsHandlerFromConfig returning an error for the chosen metrics reporter settings.","commonSituations":"Typo in config/template yaml (metrics.prometheus.bindAddress invalid), port already in use, unsupported SDK metrics scope settings, missing required fields in the metrics block.","solutions":["Read the wrapped inner error and fix the metrics section of your config yaml","Verify the exporter type and bind address (prometheus) are valid and the port is free","Inject a custom handler with temporal.WithMetricHandler (fx option) if you need nonstandard metrics setup","Temporarily remove/comment the metrics block to confirm it is the failing component"],"exampleFix":"// before\nmetrics:\n  prometheus:\n    bindAddress: \"bad-address\"\n// after\nmetrics:\n  prometheus:\n    bindAddress: \"0.0.0.0:9090\"","handlingStrategy":"validation","validationCode":"// pre-validate metrics config before starting the server\nvar cfg config.Metrics\nif err := yaml.Unmarshal(metricsYaml, &cfg); err != nil { log.Fatal(err) }\nif cfg.Prometheus != nil {\n    if _, _, err := net.SplitHostPort(cfg.Prometheus.BindAddress); err != nil {\n        log.Fatalf(\"invalid prometheus bindAddress: %v\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint/validate the server config yaml in CI (temporal server config validation)","Check that prometheus bind ports are free in the deployment environment","Derive config from the shipped config/template files instead of hand-writing from scratch"],"tags":["metrics","config","startup","fx","go"],"backgroundTag":"invalid-metric-config","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}