{"record":{"id":"8be93ba2c15b7433","repo":"juanfont/headscale","slug":"system-checks-failed","errorCode":null,"errorMessage":"system checks failed","messagePattern":"system checks failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/hi/doctor.go","lineNumber":29,"sourceCode":"\n\t\"github.com/juanfont/headscale/integration/dockertestutil\"\n\t\"github.com/juanfont/headscale/integration/k3sic\"\n)\n\nconst (\n\tstatusPass = \"PASS\"\n\tstatusFail = \"FAIL\"\n\tstatusWarn = \"WARN\"\n\n\tnameDockerDaemon  = \"Docker Daemon\"\n\tnameDockerContext = \"Docker Context\"\n\tnameDockerSocket  = \"Docker Socket\"\n\tnameGolangImage   = \"Golang Image\"\n\tnameK3sImage      = \"K3s Image\"\n\tnameGoInstall     = \"Go Installation\"\n)\n\nvar ErrSystemChecksFailed = errors.New(\"system checks failed\")\n\n// DoctorResult represents the result of a single health check.\ntype DoctorResult struct {\n\tName        string\n\tStatus      string // \"PASS\", \"FAIL\", \"WARN\"\n\tMessage     string\n\tSuggestions []string\n}\n\n// pass builds a passing DoctorResult.\nfunc pass(name, message string) DoctorResult {\n\treturn DoctorResult{Name: name, Status: statusPass, Message: message}\n}\n\n// warn builds a warning DoctorResult with optional suggestions.\nfunc warn(name, message string, suggestions ...string) DoctorResult {\n\treturn DoctorResult{Name: name, Status: statusWarn, Message: message, Suggestions: suggestions}\n}","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/cmd/hi/doctor.go#L11-L47","documentation":"Guard error from doLoginURLWithClient when loginURL is nil. The function immediately dereferences loginURL.String(), so a nil URL is rejected up front with the hostname for context.","triggerScenarios":"Passing a nil *url.URL — typically because a prior step that extracts the login URL from tailscaled output failed and returned nil, and the caller ignored that error.","commonSituations":"Login URL parsing/extraction failed earlier (tailscale not in NeedsLogin state, `tailscale login` output format changed), error ignored, nil propagated into this function.","solutions":["Check where the loginURL was obtained; verify that step's error was handled.","Confirm the node is in NeedsLogin state before extracting a login URL."],"exampleFix":"// before\nloginURL, _ := client.GetLoginURL()\nbody, redir, err := doLoginURLWithClient(hostname, loginURL, hc, true)\n// after\nloginURL, err := client.GetLoginURL()\nif err != nil || loginURL == nil {\n    return \"\", nil, fmt.Errorf(\"getting login URL: %w\", err)\n}\nbody, redir, err := doLoginURLWithClient(hostname, loginURL, hc, true)","handlingStrategy":"type-guard","validationCode":"if loginURL == nil || loginURL.String() == \"\" {\n    return fmt.Errorf(\"login URL missing; is the node in NeedsLogin state?\")\n}","typeGuard":"func hasLoginURL(u *url.URL) bool {\n    return u != nil && u.IsAbs() && u.Host != \"\"\n}","tryCatchPattern":null,"preventionTips":["Always handle errors from login-URL extraction steps.","Confirm the node reports NeedsLogin before requesting its login URL."],"tags":["integration","http","nil-guard","api-misuse"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}