{"record":{"id":"2000ada74ee03184","repo":"caddyserver/caddy","slug":"retrieving-current-executable-permission-bits-v","errorCode":null,"errorMessage":"retrieving current executable permission bits: %v","messagePattern":"retrieving current executable permission bits: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/packagesfuncs.go","lineNumber":133,"sourceCode":"\t\t\t// package does not exist\n\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"package is not added\")\n\t\t}\n\t\tdelete(pluginPkgs, arg)\n\t}\n\n\treturn upgradeBuild(pluginPkgs, fl)\n}\n\nfunc upgradeBuild(pluginPkgs map[string]pluginPackage, fl Flags) (int, error) {\n\tl := caddy.Log()\n\n\tthisExecPath, err := os.Executable()\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"determining current executable path: %v\", err)\n\t}\n\tthisExecStat, err := os.Stat(thisExecPath)\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"retrieving current executable permission bits: %v\", err)\n\t}\n\tif thisExecStat.Mode()&os.ModeSymlink == os.ModeSymlink {\n\t\tsymSource := thisExecPath\n\t\t// we are a symlink; resolve it\n\t\tthisExecPath, err = filepath.EvalSymlinks(thisExecPath)\n\t\tif err != nil {\n\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"resolving current executable symlink: %v\", err)\n\t\t}\n\t\tl.Info(\"this executable is a symlink\", zap.String(\"source\", symSource), zap.String(\"target\", thisExecPath))\n\t}\n\tl.Info(\"this executable will be replaced\", zap.String(\"path\", thisExecPath))\n\n\t// build the request URL to download this custom build\n\tqs := url.Values{\n\t\t\"os\":   {runtime.GOOS},\n\t\t\"arch\": {runtime.GOARCH},\n\t}\n\tfor _, pkgInfo := range pluginPkgs {","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/packagesfuncs.go#L115-L151","documentation":"upgradeBuild stat'ed the resolved executable path to capture its permission bits (needed so the replacement binary keeps the same mode) and os.Stat failed — the path returned by os.Executable no longer exists or is inaccessible.","triggerScenarios":"The binary was deleted or moved between os.Executable and os.Stat (e.g. a concurrent package manager operation, or a leftover broken state from a previous failed upgrade); permission changes that make the directory non-traversable.","commonSituations":"Racing `apt upgrade`/`brew upgrade` while running `caddy upgrade`; containers where the binary lives on an overlay that changed; leftover `.tmp` backup from an earlier interrupted run.","solutions":["Reinstall the binary to a stable path (official download or xcaddy) so stat succeeds","Ensure no concurrent package-manager operations touch the Caddy binary during upgrade","Check for and clean up stale artifacts like `caddy.tmp`, then retry `caddy upgrade`"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"P=$(command -v caddy); [ -f \"$P\" ] && [ -x \"$P\" ] || echo 'caddy binary missing; reinstall before upgrade'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not run concurrent package-manager operations on the Caddy binary","Clean stale caddy.tmp artifacts from failed upgrades"],"tags":["caddy","upgrade","filesystem","race","cli"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}