{"record":{"id":"edb520475d2f80f1","repo":"cloudflare/cloudflared","slug":"http-s-ready-endpoint-returned-status-code-d","errorCode":null,"errorMessage":"http://%s/ready endpoint returned status code %d\n%s","messagePattern":"http://(.+?)/ready endpoint returned status code (.+?)\n(.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cloudflared/tunnel/subcommands.go","lineNumber":503,"sourceCode":"\t}\n\n\trequestURL := fmt.Sprintf(\"http://%s/ready\", metricsOpts)\n\treq, err := http.NewRequest(http.MethodGet, requestURL, nil)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// nolint: gosec // URL is constructed from the user-configured local metrics endpoint.\n\tres, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() { _ = res.Body.Close() }()\n\tif res.StatusCode != 200 {\n\t\tbody, err := io.ReadAll(res.Body)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn fmt.Errorf(\"http://%s/ready endpoint returned status code %d\\n%s\", metricsOpts, res.StatusCode, body)\n\t}\n\treturn nil\n}\n\nfunc buildInfoCommand() *cli.Command {\n\treturn &cli.Command{\n\t\tName:        \"info\",\n\t\tAction:      cliutil.ConfiguredAction(tunnelInfo),\n\t\tUsage:       \"List details about the active connectors for a tunnel\",\n\t\tUsageText:   \"cloudflared tunnel [tunnel command options] info [subcommand options] [TUNNEL]\",\n\t\tDescription: \"cloudflared tunnel info displays details about the active connectors for a given tunnel (identified by name or uuid).\",\n\t\tFlags: []cli.Flag{\n\t\t\toutputFormatFlag,\n\t\t\tshowRecentlyDisconnected,\n\t\t\tsortInfoByFlag,\n\t\t\tinvertInfoSortFlag,\n\t\t},\n\t\tCustomHelpTemplate: commandHelpTemplate(),","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/cloudflare/cloudflared/blob/2253eeeb25a44a713a4b60b8ba1e1b3f377d1a0f/cmd/cloudflared/tunnel/subcommands.go#L485-L521","documentation":"readyCommand probes a running cloudflared instance's metrics/ready endpoint (http://<metrics-host>/ready) and expects HTTP 200. Any other status code (e.g. 503 when no connections are established yet) is converted into this error including the response body, since it means the instance is not healthy.","triggerScenarios":"Running `cloudflared tunnel ready` against an instance whose /ready endpoint returns non-200 — typically a tunnel that has not yet established its edge connections, or whose metrics address is wrong and is answered by a different server.","commonSituations":"Health-check scripts racing tunnel startup (ready before connections complete); pointing at a host where another service returns 404; the running cloudflared lost its edge connections and reports 503.","solutions":["Wait for the tunnel to finish connecting, then retry `cloudflared tunnel ready` (add retry/backoff in health-check scripts).","Check tunnel logs (`cloudflared tunnel run` output) for edge connection failures if 503 persists.","Verify the --metrics address matches the one the running instance was started with."],"exampleFix":"// before\ncloudflared tunnel ready --url http://localhost:20241\n// after\nfor i in $(seq 1 30); do\n  cloudflared tunnel ready --url http://localhost:20241 && break\n  sleep 2\ndone","handlingStrategy":"retry","validationCode":"resp, err := http.Get(\"http://localhost:20241/ready\")\nif err == nil && resp.StatusCode != http.StatusOK {\n    // not ready yet — wait before running the ready command\n    time.Sleep(2 * time.Second)\n}","typeGuard":null,"tryCatchPattern":"// backoff loop around the ready probe\nfor i := 0; i < 15; i++ {\n    if err := readyCheck(); err == nil { return nil }\n    time.Sleep(2 * time.Second)\n}\nreturn fmt.Errorf(\"tunnel never became ready: %w\", err)","preventionTips":["Only probe /ready after the tunnel process has had time to establish edge connections.","Verify the --metrics address matches the running instance.","Add retry/backoff to health-check scripts instead of failing on first non-200."],"tags":["http","health-check","cli","readiness"],"backgroundTag":"http-non-200-response","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"}