{"record":{"id":"fd8b716770cc4dd3","repo":"tailscale/tailscale","slug":"cmd-tailscale-version-q-does-not-match-tailscaled","errorCode":null,"errorMessage":"cmd/tailscale version %q does not match tailscaled version %q","messagePattern":"cmd/tailscale version %q does not match tailscaled version %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"feature/clientupdate/clientupdate.go","lineNumber":453,"sourceCode":"\t\t}\n\t}()\n\n\tcmdTS, err := findCmdTailscale()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to find cmd/tailscale binary: %w\", err)\n\t}\n\tvar ver struct {\n\t\tLong string `json:\"long\"`\n\t}\n\tout, err := exec.Command(cmdTS, \"version\", \"--json\").Output()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to find cmd/tailscale binary: %w\", err)\n\t}\n\tif err := json.Unmarshal(out, &ver); err != nil {\n\t\treturn fmt.Errorf(\"invalid JSON from cmd/tailscale version --json: %w\", err)\n\t}\n\tif ver.Long != version.Long() {\n\t\treturn fmt.Errorf(\"cmd/tailscale version %q does not match tailscaled version %q\", ver.Long, version.Long())\n\t}\n\n\tcmd := tailscaleUpdateCmd(cmdTS)\n\tbuf := new(bytes.Buffer)\n\tcmd.Stdout = buf\n\tcmd.Stderr = buf\n\te.logf(\"%s: running %q\", logPrefix, strings.Join(cmd.Args, \" \"))\n\tif err := cmd.Start(); err != nil {\n\t\treturn fmt.Errorf(\"failed to start cmd/tailscale update: %w\", err)\n\t}\n\n\tgo func() {\n\t\tif err := cmd.Wait(); err != nil {\n\t\t\te.logf(\"%s: update command failed: %v, output: %s\", logPrefix, err, buf)\n\t\t} else {\n\t\t\te.logf(\"%s: update attempt complete\", logPrefix)\n\t\t}\n\t\te.setC2NUpdateStarted(false)","sourceCodeStart":435,"sourceCodeEnd":471,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/feature/clientupdate/clientupdate.go#L435-L471","documentation":"Before delegating a self-update to the CLI, tailscaled compares the CLI's reported long version string against its own version.Long() and refuses when they differ. `tailscale update` must update the exact package/install the daemon belongs to, so a mismatched pair is a hard stop.","triggerScenarios":"ver.Long != version.Long() after parsing the CLI's JSON: tailscaled is 1.66.0 while /usr/bin/tailscale is 1.72.0; one binary was replaced but not the other; dev builds whose long strings differ (different commit, `-dev`/dirty suffixes, different build tags).","commonSituations":"Half-completed upgrades where the package manager replaced tailscaled but not tailscale (or the daemon was not restarted); mixing tarball installs in /usr/local with distro packages in /usr; building one binary from source and keeping the other from a release.","solutions":["Run `tailscale version` and `tailscaled --version` side by side and compare the long strings","Upgrade or reinstall both binaries together from one release (apt/dnf upgrade, brew upgrade, MSI, official tarball)","Restart tailscaled after upgrading so the running daemon matches its on-disk binary","For source builds, rebuild and install cmd/tailscale and cmd/tailscaled from the same commit and flags"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"out, _ := exec.Command(cmdTS, \"version\", \"--json\").Output()\nvar v struct{ Long string `json:\"long\"` }\nif json.Unmarshal(out, &v) == nil && v.Long != version.Long() {\n\treturn fmt.Errorf(\"refusing update: CLI %s != daemon %s; upgrade both binaries together\", v.Long, version.Long())\n}","typeGuard":null,"tryCatchPattern":"if err := updater.Update(...); err != nil {\n\tif strings.Contains(err.Error(), \"does not match tailscaled version\") {\n\t\t// surface an 'upgrade both binaries / restart daemon' instruction to the operator\n\t}\n}","preventionTips":["Deploy both binaries atomically from a single release artifact","Restart tailscaled as part of every upgrade runbook step","In clusters, drain and upgrade nodes one at a time instead of replacing halves of the pair"],"tags":["tailscale","go","client-update","version-mismatch"],"backgroundTag":"version-mismatch","analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}