{"record":{"id":"3cd9479fa481e465","repo":"juanfont/headscale","slug":"s-failed-to-fetch-tailscale-status-w","errorCode":null,"errorMessage":"%s failed to fetch tailscale status: %w","messagePattern":"(.+?) failed to fetch tailscale status: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integration/tsic/tsic.go","lineNumber":80,"sourceCode":"\terrTailscalePingFailed             = errors.New(\"ping failed\")\n\terrTailscalePingNotDERP            = errors.New(\"ping not via DERP\")\n\terrTailscaleNotLoggedIn            = errors.New(\"tailscale not logged in\")\n\terrTailscaleWrongPeerCount         = errors.New(\"wrong peer count\")\n\terrTailscaleCannotUpWithoutAuthkey = errors.New(\"cannot up without authkey\")\n\terrInvalidClientConfig             = errors.New(\"verifiably invalid client config requested\")\n\terrInvalidTailscaleImageFormat     = errors.New(\"invalid HEADSCALE_INTEGRATION_TAILSCALE_IMAGE format, expected repository:tag\")\n\terrTailscaleImageRequiredInCI      = errors.New(\"HEADSCALE_INTEGRATION_TAILSCALE_IMAGE must be set in CI for HEAD version\")\n\terrContainerNotInitialized         = errors.New(\"container not initialized\")\n\terrFQDNNotYetAvailable             = errors.New(\"FQDN not yet available\")\n\terrCurlEmptyResponseBody           = errors.New(\"curl returned empty response body\")\n)\n\nconst (\n\tVersionHead = \"head\"\n)\n\nfunc errTailscaleStatus(hostname string, err error) error {\n\treturn fmt.Errorf(\"%s failed to fetch tailscale status: %w\", hostname, err)\n}\n\n// TailscaleInContainer is an implementation of TailscaleClient which\n// sets up a Tailscale instance inside a container.\ntype TailscaleInContainer struct {\n\tversion  string\n\thostname string\n\n\tpool      *dockertest.Pool\n\tcontainer *dockertest.Resource\n\tnetwork   *dockertest.Network\n\n\t// \"cache\"\n\tips  []netip.Addr\n\tfqdn string\n\n\t// optional config\n\tcaCerts           [][]byte","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/integration/tsic/tsic.go#L62-L98","documentation":"A `TailscaleInContainer` client failed to run `tailscale status` inside its container; `errTailscaleStatus(hostname, err)` is the annotated wrapper used by all status-dependent helpers (IPs, FQDN, login state). The wrapped error is the exec failure from dockertest.","triggerScenarios":"Any helper that shells out to `tailscale status` while tailscaled is not running yet, the binary is missing in the container, the socket is down, or tailscaled exited with an error.","commonSituations":"Querying a client immediately after container start before tailscaled is up; container image built without tailscale installed; tailscaled crashed due to bad flags; test teardown raced the query.","solutions":["Read the wrapped exec error — 'tailscaled not running' vs 'connection refused' points to readiness vs crash.","Wrap status queries in an Eventually/retry loop rather than calling them once.","Check the client container logs for a tailscaled startup crash.","If the binary is missing, rebuild the tailscale image (or set HEADSCALE_INTEGRATION_TAILSCALE_IMAGE)."],"exampleFix":"// before\nips, err := client.IPs() // one-shot, races tailscaled startup\n\n// after\nvar ips []netip.Addr\nrequire.EventuallyWithT(t, func(c *assert.CollectT) {\n    var err error\n    ips, err = client.IPs()\n    assert.NoError(c, err)\n}, 30*time.Second, time.Second)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"// All status-dependent helpers should sit inside an Eventually.\nrequire.EventuallyWithT(t, func(c *assert.CollectT) {\n    _, err := client.IPs()\n    assert.NoError(c, err)\n}, 60*time.Second, time.Second)","preventionTips":["Never call status helpers right after container start; wait for tailscaled.","Read client container logs when status keeps failing.","Ensure the tailscale image actually contains the binary before running flows."],"tags":["tailscale","integration","readiness","docker"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}