{"record":{"id":"b59f80f2c7df7176","repo":"caddyserver/caddy","slug":"no-build-info","errorCode":null,"errorMessage":"no build info","messagePattern":"no build info","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/packagesfuncs.go","lineNumber":219,"sourceCode":"\n\t// clean up the backup file\n\tif !fl.Bool(\"keep-backup\") {\n\t\tif err = removeCaddyBinary(backupExecPath); err != nil {\n\t\t\treturn caddy.ExitCodeFailedStartup, fmt.Errorf(\"download succeeded, but unable to clean up backup binary: %v\", err)\n\t\t}\n\t} else {\n\t\tl.Info(\"skipped cleaning up the backup file\", zap.String(\"backup_path\", backupExecPath))\n\t}\n\n\tl.Info(\"upgrade successful; please restart any running Caddy instances\", zap.String(\"executable\", thisExecPath))\n\n\treturn caddy.ExitCodeSuccess, nil\n}\n\nfunc getModules() (standard, nonstandard, unknown []moduleInfo, err error) {\n\tbi, ok := debug.ReadBuildInfo()\n\tif !ok {\n\t\terr = fmt.Errorf(\"no build info\")\n\t\treturn standard, nonstandard, unknown, err\n\t}\n\n\tfor _, modID := range caddy.Modules() {\n\t\tmodInfo, err := caddy.GetModule(modID)\n\t\tif err != nil {\n\t\t\t// that's weird, shouldn't happen\n\t\t\tunknown = append(unknown, moduleInfo{caddyModuleID: modID, err: err})\n\t\t\tcontinue\n\t\t}\n\n\t\t// to get the Caddy plugin's version info, we need to know\n\t\t// the package that the Caddy module's value comes from; we\n\t\t// can use reflection but we need a non-pointer value (I'm\n\t\t// not sure why), and since New() should return a pointer\n\t\t// value, we need to dereference it first\n\t\tiface := any(modInfo.New())\n\t\tif rv := reflect.ValueOf(iface); rv.Kind() == reflect.Pointer {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/packagesfuncs.go#L201-L237","documentation":"getModules() calls debug.ReadBuildInfo(), which returns ok=false when the binary carries no embedded Go build metadata. Without build info, caddy cannot enumerate which plugins (non-standard modules) are compiled in, so 'upgrade', 'add-package', 'remove-package', and 'list-modules' cannot compute the package list to send to the build API.","triggerScenarios":"The caddy binary was compiled in a way that strips build info: built with 'go build -ldflags=\"-s -w\"' plus manual stripping, built in GOPATH mode (go run from a non-module dir), produced by a tool that rewrites the binary (some packers/obfuscators like garble), or assembled from objects without module context.","commonSituations":"Using a caddy binary repackaged by a Linux distribution that strips binaries (strip(1) removes build info); custom builds hardened with garble; compiling after copying sources out of a module tree.","solutions":["Build from a proper module checkout: git clone + xcaddy build (or go install github.com/caddyserver/caddy/cmd/caddy@latest from within any module)","If distro-packaged, prefer the official binaries from caddyserver.com or GitHub releases, then use 'caddy upgrade'","If stripping is deliberate (garble, strip), accept that package-management commands are unavailable and rebuild manually with xcaddy to change plugins"],"exampleFix":"# before\nstrip /usr/local/bin/caddy   # removes build info\ncaddy upgrade               # error: no build info\n\n# after\nxcaddy build                 # produces a binary with build info\ncaddy upgrade","handlingStrategy":"validation","validationCode":"go version -m \"$(command -v caddy)\" >/dev/null 2>&1 || echo 'binary has no build info; rebuild with xcaddy'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build custom binaries with xcaddy so build info is embedded","Never strip caddy binaries (strip -s, garble) if you plan to use upgrade/add-package","Verify with 'go version -m $(which caddy)' before relying on package management commands"],"tags":["build-info","upgrade","toolchain"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}