{"record":{"id":"1cace4ffd864ba88","repo":"cloudflare/cloudflared","slug":"error-opening-metrics-server-listener","errorCode":null,"errorMessage":"Error opening metrics server listener","messagePattern":"Error opening metrics server listener","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/tunnel/cmd.go","lineNumber":462,"sourceCode":"\tmgmt := management.New(\n\t\tmanagementHostname,\n\t\tc.Bool(\"management-diagnostics\"),\n\t\tserviceIP,\n\t\tconnectorID,\n\t\tc.String(cfdflags.ConnectorLabel),\n\t\tlogger.ManagementLogger.Log,\n\t\tlogger.ManagementLogger,\n\t)\n\tinternalRules := []ingress.Rule{ingress.NewManagementRule(mgmt)}\n\torchestrator, err := orchestration.NewOrchestrator(ctx, orchestratorConfig, tunnelConfig.Tags, internalRules, tunnelConfig.Log)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tmetricsListener, err := metrics.CreateMetricsListener(&listeners, c.String(\"metrics\"))\n\tif err != nil {\n\t\tlog.Err(err).Msg(\"Error opening metrics server listener\")\n\t\treturn errors.Wrap(err, \"Error opening metrics server listener\")\n\t}\n\n\tdefer func() { _ = metricsListener.Close() }()\n\twg.Add(1)\n\n\tgo func() {\n\t\tdefer wg.Done()\n\t\ttracker := tunnelstate.NewConnTracker(log)\n\t\tobserver.RegisterSink(tracker)\n\n\t\tipv4, ipv6, err := determineICMPSources(c, log)\n\t\tsources := make([]string, 0)\n\t\tif err == nil {\n\t\t\tsources = append(sources, ipv4.String())\n\t\t\tsources = append(sources, ipv6.String())\n\t\t}\n\n\t\treadinessServer := metrics.NewReadyServer(connectorID, tracker)","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/tunnel/cmd.go#L444-L480","documentation":"cloudflared wraps the error returned by metrics.CreateMetricsListener when the metrics HTTP server cannot open its listener socket. The metrics listener binds an address like 127.0.0.1:metrics (or --metrics value) so prometheus metrics can be scraped; if that bind fails the tunnel refuses to start. The error is both logged and wrapped before aborting StartServer.","triggerScenarios":"Running `cloudflared tunnel run` (via RunQuickTunnel or runWithCredentials -> StartServer) with a --metrics address that is already bound, invalid, or unbindable (e.g. privileged port without permissions, bad hostname).","commonSituations":"Two cloudflared instances running with the same default metrics port (2024x); container environments where 0.0.0.0 binding is blocked; typo'd --metrics flag value like 'localhost:99999'; port occupied by another monitoring agent.","solutions":["Check what is using the metrics port (lsof -i :<port> / netstat) and stop the conflicting process.","Set --metrics to a free address/port, e.g. --metrics 127.0.0.1:20241, or 127.0.0.1:0 to pick an ephemeral port.","Disable metrics entirely with --metrics none if scraping is not needed.","Verify the --metrics value is a valid host:port; fix typos or out-of-range ports."],"exampleFix":"// before\ncloudflared tunnel run --metrics localhost:20241 my-tunnel\n// error: port already in use\n// after\ncloudflared tunnel run --metrics 127.0.0.1:20245 my-tunnel","handlingStrategy":"validation","validationCode":"// check the port is free before starting\nimport \"net\"\nfunc metricsAddrAvailable(addr string) bool {\n\tln, err := net.Listen(\"tcp\", addr)\n\tif err != nil { return false }\n\t_ = ln.Close()\n\treturn true\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n\tlog.Err(err).Msg(\"Error opening metrics server listener\")\n\treturn fmt.Errorf(\"metrics listener on %s unavailable: %w\", metricsAddr, err)\n}","preventionTips":["Pick a unique metrics port per cloudflared instance","Use 127.0.0.1:0 for an ephemeral port when scraping config can follow the logs","Use `--metrics none` when metrics are not needed","Monitor ports with lsof/netstat before deployments"],"tags":["network","metrics","port-binding","cli"],"backgroundTag":"address-already-in-use","analyzedSha":"2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f","analyzedAt":"2026-09-06T04:14:33.757Z","contentChangedAt":"2026-09-06T04:14:33.757Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}