{"record":{"id":"d0849235b60267f2","repo":"caddyserver/caddy","slug":"unable-to-enumerate-installed-plugins-v","errorCode":null,"errorMessage":"unable to enumerate installed plugins: %v","messagePattern":"unable to enumerate installed plugins: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/packagesfuncs.go","lineNumber":39,"sourceCode":"\t\"net/http\"\n\t\"net/url\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"runtime\"\n\t\"runtime/debug\"\n\t\"strings\"\n\n\t\"go.uber.org/zap\"\n\n\t\"github.com/caddyserver/caddy/v2\"\n)\n\nfunc cmdUpgrade(fl Flags) (int, error) {\n\t_, nonstandard, _, err := getModules()\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"unable to enumerate installed plugins: %v\", err)\n\t}\n\tpluginPkgs, err := getPluginPackages(nonstandard)\n\tif err != nil {\n\t\treturn caddy.ExitCodeFailedStartup, err\n\t}\n\n\treturn upgradeBuild(pluginPkgs, fl)\n}\n\nfunc splitModule(arg string) (module, version string, err error) {\n\tconst versionSplit = \"@\"\n\n\t// accommodate module paths that have @ in them, but we can only tolerate that if there's also\n\t// a version, otherwise we don't know if it's a version separator or part of the file path\n\tlastVersionSplit := strings.LastIndex(arg, versionSplit)\n\tif lastVersionSplit < 0 {\n\t\tmodule = arg\n\t} else {","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/packagesfuncs.go#L21-L57","documentation":"`caddy upgrade` fails before doing anything when getModules() cannot enumerate installed plugins. getModules reads the binary's embedded Go build information (debug.ReadBuildInfo) and reflects over registered Caddy modules; the most common underlying error is 'no build info', meaning the running binary was compiled without module metadata.","triggerScenarios":"Running `caddy upgrade` on a binary built from a GOPATH-style build, cross-compiled in a way that strips build info, produced by some packagers (Homebrew/binary distributions rebuilt), or stripped with tools that remove the buildinfo section. A corrupted binary has the same effect.","commonSituations":"A Caddy binary installed by a distro package or built ad-hoc with `go build` from a vendored snapshot lacking module info; binaries copied out of scratch containers where buildinfo was stripped.","solutions":["Check the nested error: 'no build info' means the binary cannot self-describe its plugins","Reinstall an official binary: `curl -sSL https://caddyserver.com/api/download?os=linux&arch=amd64 -o caddy` or use the official package","Prefer xcaddy for custom builds: `xcaddy build` produces a binary with full build info and supports `--with` plugins","If you maintain a custom build, ensure it is built as a Go module (`go build` inside a module, no -ldflags stripping of buildinfo)"],"exampleFix":"# before\ncaddy upgrade   # fails: unable to enumerate installed plugins\n\n# after\nxcaddy build --with github.com/caddy-dns/cloudflare","handlingStrategy":"validation","validationCode":"# a binary that supports upgrade must carry build info\nif ! strings \"$(command -v caddy)\" | grep -q '^go1\\.'; then echo 'binary lacks Go build info; use xcaddy or official download'; fi\n# stronger check: does it list versions?\ncaddy list-modules --versions >/dev/null || echo 'module introspection broken'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install Caddy from official releases or xcaddy, not distro rebuilds","Standardize on xcaddy for plugin builds; treat in-place `caddy upgrade` as convenience only"],"tags":["caddy","upgrade","build-info","cli","plugins"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}