caddyserver/caddy · error

no build info

Error message

no build info

What it means

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.

Source

Thrown at cmd/packagesfuncs.go:219

	// clean up the backup file
	if !fl.Bool("keep-backup") {
		if err = removeCaddyBinary(backupExecPath); err != nil {
			return caddy.ExitCodeFailedStartup, fmt.Errorf("download succeeded, but unable to clean up backup binary: %v", err)
		}
	} else {
		l.Info("skipped cleaning up the backup file", zap.String("backup_path", backupExecPath))
	}

	l.Info("upgrade successful; please restart any running Caddy instances", zap.String("executable", thisExecPath))

	return caddy.ExitCodeSuccess, nil
}

func getModules() (standard, nonstandard, unknown []moduleInfo, err error) {
	bi, ok := debug.ReadBuildInfo()
	if !ok {
		err = fmt.Errorf("no build info")
		return standard, nonstandard, unknown, err
	}

	for _, modID := range caddy.Modules() {
		modInfo, err := caddy.GetModule(modID)
		if err != nil {
			// that's weird, shouldn't happen
			unknown = append(unknown, moduleInfo{caddyModuleID: modID, err: err})
			continue
		}

		// to get the Caddy plugin's version info, we need to know
		// the package that the Caddy module's value comes from; we
		// can use reflection but we need a non-pointer value (I'm
		// not sure why), and since New() should return a pointer
		// value, we need to dereference it first
		iface := any(modInfo.New())
		if rv := reflect.ValueOf(iface); rv.Kind() == reflect.Pointer {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Build from a proper module checkout: git clone + xcaddy build (or go install github.com/caddyserver/caddy/cmd/caddy@latest from within any module)
  2. If distro-packaged, prefer the official binaries from caddyserver.com or GitHub releases, then use 'caddy upgrade'
  3. If stripping is deliberate (garble, strip), accept that package-management commands are unavailable and rebuild manually with xcaddy to change plugins

Example fix

# before
strip /usr/local/bin/caddy   # removes build info
caddy upgrade               # error: no build info

# after
xcaddy build                 # produces a binary with build info
caddy upgrade
Defensive patterns

Strategy: validation

Validate before calling

go version -m "$(command -v caddy)" >/dev/null 2>&1 || echo 'binary has no build info; rebuild with xcaddy'

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/b59f80f2c7df7176. Report an issue: GitHub.