{"record":{"id":"927775c548aa0936","repo":"juanfont/headscale","slug":"creating-tailscale-node-w","errorCode":null,"errorMessage":"creating tailscale node: %w","messagePattern":"creating tailscale node: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"integration/helpers.go","lineNumber":1160,"sourceCode":"func (s *Scenario) AddAndLoginClient(\n\tt *testing.T,\n\tusername string,\n\tversion string,\n\theadscale ControlServer,\n\ttsOpts ...tsic.Option,\n) (TailscaleClient, error) {\n\tt.Helper()\n\n\t// Get the original client list\n\toriginalClients, err := s.ListTailscaleClients(username)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"listing original clients: %w\", err)\n\t}\n\n\t// Create the new node\n\terr = s.CreateTailscaleNodesInUser(username, version, 1, tsOpts...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating tailscale node: %w\", err)\n\t}\n\n\t// Wait for the new node to appear in the client list\n\tvar newClient TailscaleClient\n\n\t_, err = backoff.Retry(t.Context(), func() (struct{}, error) {\n\t\tupdatedClients, err := s.ListTailscaleClients(username)\n\t\tif err != nil {\n\t\t\treturn struct{}{}, fmt.Errorf(\"listing updated clients: %w\", err)\n\t\t}\n\n\t\tif len(updatedClients) != len(originalClients)+1 {\n\t\t\treturn struct{}{}, fmt.Errorf(\"expected %d clients, got %d\", len(originalClients)+1, len(updatedClients)) //nolint:err113\n\t\t}\n\n\t\tnewClient, err = FindNewClient(originalClients, updatedClients)\n\t\tif err != nil {\n\t\t\treturn struct{}{}, fmt.Errorf(\"finding new client: %w\", err)","sourceCodeStart":1142,"sourceCodeEnd":1178,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/integration/helpers.go#L1142-L1178","documentation":"Returned by Scenario.AddAndLoginClient when s.CreateTailscaleNodesInUser fails to create and start the new tailscale node container. It wraps the underlying container-creation error; the subsequent 'wait for it to appear' phase never runs.","triggerScenarios":"Calling AddAndLoginClient with a tailscale version whose image cannot be pulled/built, or Docker failing to start the container (resource limits, name/network conflicts).","commonSituations":"Testing an unreleased tailscale version whose image isn't built locally; Docker network/subnet exhaustion from prior runs; CI disk pressure preventing container start.","solutions":["Verify the tailscale image for the requested version exists locally or is pullable","Clean up Docker leftovers (networks, stopped containers) from earlier failed runs","Free host resources or lower test parallelism, then retry the scenario"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// preflight: image exists locally or is pullable\nfunc imageAvailable(ref string) bool {\n    // docker image inspect ref || docker pull ref\n    return true // implement with your docker client of choice\n}","typeGuard":null,"tryCatchPattern":"c, err := s.AddAndLoginClient(t, user, ver, h, opts...)\nif err != nil && strings.Contains(err.Error(), \"creating tailscale node\") {\n    // prune leftovers, verify image for ver, retry once\n}","preventionTips":["Build/pull tailscale test images before the suite starts, not lazily per test","Run docker cleanup (hi cleanup) after failed runs to prevent network exhaustion"],"tags":["integration-test","scenario","docker","clients"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}