{"record":{"id":"5c46a865e975e1bc","repo":"tailscale/tailscale","slug":"starting-tailscaled-failed-w","errorCode":null,"errorMessage":"starting tailscaled failed: %w","messagePattern":"starting tailscaled failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cmd/containerboot/tailscaled.go","lineNumber":41,"sourceCode":"\t\"tailscale.com/client/local\"\n)\n\nfunc startTailscaled(ctx context.Context, cfg *settings) (*local.Client, *os.Process, error) {\n\targs := tailscaledArgs(cfg)\n\t// tailscaled runs without context, since it needs to persist\n\t// beyond the startup timeout in ctx.\n\tcmd := exec.Command(\"tailscaled\", args...)\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\tcmd.SysProcAttr = &syscall.SysProcAttr{\n\t\tSetpgid: true,\n\t}\n\tif cfg.CertShareMode != \"\" {\n\t\tcmd.Env = append(os.Environ(), \"TS_CERT_SHARE_MODE=\"+cfg.CertShareMode)\n\t}\n\tlog.Printf(\"Starting tailscaled\")\n\tif err := cmd.Start(); err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"starting tailscaled failed: %w\", err)\n\t}\n\n\t// Wait for the socket file to appear, otherwise API ops will racily fail.\n\tlog.Printf(\"Waiting for tailscaled socket at %s\", cfg.Socket)\n\tfor {\n\t\tif ctx.Err() != nil {\n\t\t\treturn nil, nil, errors.New(\"timed out waiting for tailscaled socket\")\n\t\t}\n\t\t_, err := os.Stat(cfg.Socket)\n\t\tif errors.Is(err, fs.ErrNotExist) {\n\t\t\ttime.Sleep(100 * time.Millisecond)\n\t\t\tcontinue\n\t\t} else if err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"error waiting for tailscaled socket: %w\", err)\n\t\t}\n\t\tbreak\n\t}\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/tailscale/tailscale/blob/cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042/cmd/containerboot/tailscaled.go#L23-L59","documentation":"tailscaled.go:41 wraps a failure of exec.Command(\"tailscaled\", ...).Start(): the process could not even be launched. In Go this happens when the binary is not found in PATH, is not executable, or has an exec format error (wrong architecture) — distinct from tailscaled exiting later, which surfaces elsewhere.","triggerScenarios":"Container image lacks the tailscaled binary (overwritten entrypoint, distroless mismatch, broken build); PATH env in the pod excludes the binary directory; running an arm64 image on amd64 nodes or vice versa.","commonSituations":"Custom Dockerfiles that copy containerboot but not tailscaled; image tags pulled for the wrong platform; securityContext or volume mounts shadowing /usr/sbin where tailscaled lives.","solutions":["Verify the binary exists and runs: docker run --rm <image> tailscaled --version","Use the official tailscale image (or derive from it) so containerboot and tailscaled ship together","Confirm the image architecture matches the node (kubectl get node -o jsonpath='{.status.nodeInfo.architecture}')","Check the pod does not override PATH or mask the binary directory with mounts"],"exampleFix":"# before\nFROM debian:bookworm-slim\nCOPY containerboot /containerboot\n# tailscaled never installed\n# after\nFROM tailscale/tailscale:latest\nCOPY containerboot /containerboot","handlingStrategy":"validation","validationCode":"// Image build/preflight: containerboot execs 'tailscaled' by name; assert it resolves.\nif _, err := exec.LookPath(\"tailscaled\"); err != nil {\n    log.Fatal(\"tailscaled binary missing from PATH: use the official tailscale image as base\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Base custom images on tailscale/tailscale so containerboot and tailscaled ship together","Pin image digests per architecture in multi-arch clusters","CI step: docker run --rm $IMAGE tailscaled --version before promoting the image"],"tags":["containerboot","exec","docker","image","startup","go"],"backgroundTag":null,"analyzedSha":"cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042","analyzedAt":"2026-08-15T19:58:31.583Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}