{"record":{"id":"033f36ce154c9522","repo":"tailscale/tailscale","slug":"failed-writing-systemd-user-service-w","errorCode":null,"errorMessage":"failed writing systemd user service: %w","messagePattern":"failed writing systemd user service: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/systray/startup-creator.go","lineNumber":80,"sourceCode":"\n\tconfigDir, err := os.UserConfigDir()\n\tif err != nil {\n\t\thomeDir, err := os.UserHomeDir()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to locate user home: %w\", err)\n\t\t}\n\t\tconfigDir = filepath.Join(homeDir, \".config\")\n\t}\n\n\tsystemdDir := filepath.Join(configDir, \"systemd\", \"user\")\n\tif err := os.MkdirAll(systemdDir, 0o755); err != nil {\n\t\treturn fmt.Errorf(\"failed creating systemd user dir: %w\", err)\n\t}\n\n\tserviceFile := filepath.Join(systemdDir, \"tailscale-systray.service\")\n\n\tif err := os.WriteFile(serviceFile, output.Bytes(), 0o755); err != nil {\n\t\treturn fmt.Errorf(\"failed writing systemd user service: %w\", err)\n\t}\n\n\tfmt.Printf(\"Successfully installed systemd service to: %s\\n\", serviceFile)\n\tfmt.Println(\"To enable and start the service, run:\")\n\tfmt.Println(\"  systemctl --user daemon-reload\")\n\tfmt.Println(\"  systemctl --user enable --now tailscale-systray\")\n\n\treturn nil\n}\n\nfunc installFreedesktop() error {\n\ttmpDir, err := os.MkdirTemp(\"\", \"tailscale-systray\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to make tmpDir: %w\", err)\n\t}\n\tdefer os.RemoveAll(tmpDir)\n\n\t// Install icon, and use it if it works, and if not change to some generic","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/tailscale/tailscale/blob/cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042/client/systray/startup-creator.go#L62-L98","documentation":"Returned by installSystemd when os.WriteFile fails writing the generated unit to <configDir>/systemd/user/tailscale-systray.service with mode 0755. By this point the ExecStart= line has already been rewritten to the resolved tailscale binary path plus 'systray'. The write is the last step before the success message, so failure here leaves no partial unit on disk (WriteFile is atomic-ish: it truncates then writes).","triggerScenarios":"An existing tailscale-systray.service owned by root (from a previous sudo install) that the current user cannot overwrite; read-only home filesystem; disk full; permission denial from mandatory access control on ~/.config/systemd/user.","commonSituations":"Re-running the installer as a normal user after a first run under sudo left root-owned files; systemd user unit directories under management (immutable/overlayfs); full disks in VMs.","solutions":["If a root-owned service file exists from an earlier sudo run, remove or chown it: sudo rm ~/.config/systemd/user/tailscale-systray.service.","Confirm the directory is writable by the current user (ls -ld ~/.config/systemd/user).","Free disk space if the write fails with a no-space error.","Prefer running the installer as the same user that will own the systemd --user unit."],"exampleFix":"# before\n$ ./tailscale-systray-setup\nfailed writing systemd user service: ... permission denied\n\n# after\n$ ls -l ~/.config/systemd/user/tailscale-systray.service\n-rwxr-xr-x 1 root root ... tailscale-systray.service\n$ sudo rm ~/.config/systemd/user/tailscale-systray.service\n$ ./tailscale-systray-setup","handlingStrategy":"try-catch","validationCode":"svc := filepath.Join(configDir, \"systemd\", \"user\", \"tailscale-systray.service\")\nif fi, err := os.Stat(svc); err == nil && fi.Mode().Perm() != 0o755 {\n    // possible root-owned leftover: remove before reinstall\n}","typeGuard":"func isPermissionErr(err error) bool { return errors.Is(err, fs.ErrPermission) }","tryCatchPattern":"if err := systray.InstallStartupScript(\"systemd\"); err != nil {\n    if errors.Is(err, fs.ErrPermission) && strings.Contains(err.Error(), \"writing systemd\") {\n        // remove root-owned unit file, then retry\n    }\n}","preventionTips":["Always install as the user who will run the systemd --user unit.","Clean stale unit files between reinstalls.","Monitor disk space on the home filesystem."],"tags":["go","tailscale","systray","filesystem","systemd"],"backgroundTag":null,"analyzedSha":"cfe32b8be6a33f8e24fbc369cbfbf7c729d9e042","analyzedAt":"2026-08-15T19:58:31.583Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}