caddyserver/caddy · error
unable to enumerate installed plugins: %v
Error message
unable to enumerate installed plugins: %v
What it means
`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.
Source
Thrown at cmd/packagesfuncs.go:39
"net/http"
"net/url"
"os"
"os/exec"
"path/filepath"
"reflect"
"runtime"
"runtime/debug"
"strings"
"go.uber.org/zap"
"github.com/caddyserver/caddy/v2"
)
func cmdUpgrade(fl Flags) (int, error) {
_, nonstandard, _, err := getModules()
if err != nil {
return caddy.ExitCodeFailedStartup, fmt.Errorf("unable to enumerate installed plugins: %v", err)
}
pluginPkgs, err := getPluginPackages(nonstandard)
if err != nil {
return caddy.ExitCodeFailedStartup, err
}
return upgradeBuild(pluginPkgs, fl)
}
func splitModule(arg string) (module, version string, err error) {
const versionSplit = "@"
// accommodate module paths that have @ in them, but we can only tolerate that if there's also
// a version, otherwise we don't know if it's a version separator or part of the file path
lastVersionSplit := strings.LastIndex(arg, versionSplit)
if lastVersionSplit < 0 {
module = arg
} else {View on GitHub (pinned to 50e54ee279)
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)
Example fix
# before caddy upgrade # fails: unable to enumerate installed plugins # after xcaddy build --with github.com/caddy-dns/cloudflare
Defensive patterns
Strategy: validation
Validate before calling
# a binary that supports upgrade must carry build info if ! strings "$(command -v caddy)" | grep -q '^go1\.'; then echo 'binary lacks Go build info; use xcaddy or official download'; fi # stronger check: does it list versions? caddy list-modules --versions >/dev/null || echo 'module introspection broken'
Prevention
- Install Caddy from official releases or xcaddy, not distro rebuilds
- Standardize on xcaddy for plugin builds; treat in-place `caddy upgrade` as convenience only
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- package is already added
- package is not added
- retrieving current executable permission bits: %v
- resolving current executable symlink: %v
- download failed: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/d0849235b60267f2.
Report an issue: GitHub.