{"record":{"id":"8e3e5760c35ffd52","repo":"caddyserver/caddy","slug":"backing-up-current-binary-v","errorCode":null,"errorMessage":"backing up current binary: %v","messagePattern":"backing up current binary: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/packagesfuncs.go","lineNumber":169,"sourceCode":"\tfor _, pkgInfo := range pluginPkgs {\n\t\tqs.Add(\"p\", pkgInfo.String())\n\t}\n\n\t// initiate the build\n\tresp, err := downloadBuild(qs)\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"download failed: %v\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\t// back up the current binary, in case something goes wrong we can replace it\n\tbackupExecPath := thisExecPath + \".tmp\"\n\tl.Info(\"build acquired; backing up current executable\",\n\t\tzap.String(\"current_path\", thisExecPath),\n\t\tzap.String(\"backup_path\", backupExecPath))\n\terr = os.Rename(thisExecPath, backupExecPath)\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"backing up current binary: %v\", err)\n\t}\n\tdefer func() {\n\t\tif err != nil {\n\t\t\terr2 := os.Rename(backupExecPath, thisExecPath)\n\t\t\tif err2 != nil {\n\t\t\t\tl.Error(\"restoring original executable failed; will need to be restored manually\",\n\t\t\t\t\tzap.String(\"backup_path\", backupExecPath),\n\t\t\t\t\tzap.String(\"original_path\", thisExecPath),\n\t\t\t\t\tzap.Error(err2))\n\t\t\t}\n\t\t}\n\t}()\n\n\t// download the file; do this in a closure to close reliably before we execute it\n\terr = writeCaddyBinary(thisExecPath, &resp.Body, thisExecStat)\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, err\n\t}","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/packagesfuncs.go#L151-L187","documentation":"Thrown by caddy upgrade/add-package after a custom build has been downloaded from caddyserver.com, when os.Rename fails while moving the current executable to '<exec>.tmp' before overwriting it. The upgrade aborts before anything is modified, so the original binary is untouched. The underlying cause is almost always filesystem permissions or the executable being locked by a running process.","triggerScenarios":"Running 'caddy upgrade' or 'caddy add-package' when: the directory containing the binary is not writable by the current user (e.g. /usr/bin owned by root and running unprivileged); on Windows, a caddy instance is still running so the exe file is locked; a stale '<exec>.tmp' exists as read-only; the filesystem is read-only (container, mounted volume).","commonSituations":"Installing caddy via a package manager into /usr/bin or /usr/local/bin and running 'caddy upgrade' without sudo; forgetting to stop systemd caddy service on Windows; running inside a Docker container where the binary lives on a read-only layer.","solutions":["Re-run with sufficient privileges: 'sudo caddy upgrade' (Linux/macOS) or an elevated shell on Windows","Stop all running Caddy instances before upgrading (on Windows the exe is locked while running)","Verify write permission on the binary's directory: ls -ld $(dirname $(which caddy)); chmod or chown if needed","Remove a stale read-only backup: rm -f $(which caddy).tmp","If on a read-only filesystem, copy the binary to a writable location, upgrade there, then move it back"],"exampleFix":"# before\ncaddy upgrade\n# error: backinging up current binary: rename /usr/local/bin/caddy /usr/local/bin/caddy.tmp: permission denied\n\n# after\nsudo caddy upgrade","handlingStrategy":"validation","validationCode":"# before running caddy upgrade\nEXEC=\"$(command -v caddy)\"\nDIR=\"$(dirname \"$EXEC\")\"\n[ -w \"$DIR\" ] || { echo \"not writable: $DIR (use sudo)\"; exit 1; }\n[ -f \"$EXEC.tmp\" ] && rm -f \"$EXEC.tmp\"\ndf -h \"$DIR\" | tail -1   # confirm space\n# on Windows: stop the caddy service first (sc stop caddy)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always stop running Caddy instances before 'caddy upgrade' (mandatory on Windows where the exe is locked)","Run upgrade with the privileges that own the binary's directory","Keep the caddy binary on writable local storage, never on a read-only mount","Clear stale .tmp backups before upgrading"],"tags":["upgrade","filesystem","permissions","cli"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}