{"record":{"id":"00b4826856713fd1","repo":"juanfont/headscale","slug":"inspecting-image-s-w","errorCode":null,"errorMessage":"inspecting image %s: %w","messagePattern":"inspecting image (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/hi/docker.go","lineNumber":520,"sourceCode":"\treturn nil, ErrNoDockerContext\n}\n\n// getDockerSocketPath returns the correct Docker socket path for the current context.\nfunc getDockerSocketPath() string {\n\t// Always use the default socket path for mounting since Docker handles\n\t// the translation to the actual socket (e.g., colima socket) internally\n\treturn \"/var/run/docker.sock\"\n}\n\n// checkImageAvailableLocally checks if the specified Docker image is available locally.\nfunc checkImageAvailableLocally(ctx context.Context, cli *client.Client, imageName string) (bool, error) {\n\t_, _, err := cli.ImageInspectWithRaw(ctx, imageName) //nolint:staticcheck // SA1019: deprecated but functional\n\tif err != nil {\n\t\tif client.IsErrNotFound(err) { //nolint:staticcheck // SA1019: deprecated but functional\n\t\t\treturn false, nil\n\t\t}\n\n\t\treturn false, fmt.Errorf(\"inspecting image %s: %w\", imageName, err)\n\t}\n\n\treturn true, nil\n}\n\n// ensureImageAvailable pulls imageName if missing, using Docker Hub\n// credentials and retrying transient errors.\nfunc ensureImageAvailable(ctx context.Context, cli *client.Client, imageName string, verbose bool) error {\n\tavailable, err := checkImageAvailableLocally(ctx, cli, imageName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"checking local image availability: %w\", err)\n\t}\n\n\tif available {\n\t\tif verbose {\n\t\t\tlog.Printf(\"Image %s is available locally\", imageName)\n\t\t}\n","sourceCodeStart":502,"sourceCodeEnd":538,"githubUrl":"https://github.com/juanfont/headscale/blob/565fd254d06c4c7f9a8cad1714a43445c79ba420/cmd/hi/docker.go#L502-L538","documentation":"Returned by `checkImageAvailableLocally` when `cli.ImageInspectWithRaw` fails with an error other than NotFound. NotFound itself is handled (returns available=false so a pull happens); any other daemon error — auth, API, daemon connection — gets wrapped with the image name for diagnosis.","triggerScenarios":"Daemon unreachable during inspect; API version negotiation failure; permission denied against a restricted daemon socket; image reference syntactically invalid so the daemon errors rather than reporting NotFound.","commonSituations":"Docker daemon down or restarting; user not in the docker group (permission denied on the socket); remote context endpoint stale; malformed tag in config.GoVersion.","solutions":["Verify daemon access: `docker image inspect golang:<version>` as the same user.","Add yourself to the docker group if you get permission denied (`sudo usermod -aG docker $USER`, re-login).","Fix the daemon/context (`docker context use default`).","Check the image tag syntax in RunConfig."],"exampleFix":"# before: permission denied on socket\ngo run ./cmd/hi run TestX  # inspecting image golang:...: ...permission denied\n\n# after: grant access and re-login\nsudo usermod -aG docker $USER  # then start a new shell\ngo run ./cmd/hi run TestX","handlingStrategy":"validation","validationCode":"// confirm socket access and image inspect works as this user\nif err := exec.Command(\"docker\", \"image\", \"inspect\", \"golang:\"+cfg.GoVersion).Run(); err != nil {\n    // distinguish missing image (exit 1, 'No such image') from permission/daemon errors\n    return fmt.Errorf(\"docker image inspect failed: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if _, err := checkImageAvailableLocally(ctx, cli, image); err != nil {\n    if !client.IsErrNotFound(err) {\n        // daemon-level problem: check `docker info`, socket permissions, then retry\n    }\n}","preventionTips":["Ensure the invoking user can read the docker socket (docker group + re-login).","Keep the daemon running and reachable for the whole run.","Validate image tag syntax before configuring GoVersion."],"tags":["docker","image-inspect","permissions","daemon"],"backgroundTag":null,"analyzedSha":"565fd254d06c4c7f9a8cad1714a43445c79ba420","analyzedAt":"2026-08-15T13:12:30.133Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}