caddyserver/caddy · error

download succeeded, but unable to execute 'caddy version': %

Error message

download succeeded, but unable to execute 'caddy version': %v

What it means

Same post-install verification step as the list-modules check, but for the '<newexec> version' subprocess. The new binary already replaced the old one and module listing succeeded, so a failure here is specifically about executing the binary a second time or it exiting non-zero. Because err is non-zero on return, the deferred handler restores the original binary from the .tmp backup.

Source

Thrown at cmd/packagesfuncs.go:198

		}
	}()

	// download the file; do this in a closure to close reliably before we execute it
	err = writeCaddyBinary(thisExecPath, &resp.Body, thisExecStat)
	if err != nil {
		return caddy.ExitCodeFailedStartup, err
	}

	l.Info("download successful; displaying new binary details", zap.String("location", thisExecPath))

	// use the new binary to print out version and module info
	fmt.Print("\nModule versions:\n\n")
	if err = listModules(thisExecPath); err != nil {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("download succeeded, but unable to execute 'caddy list-modules': %v", err)
	}
	fmt.Println("\nVersion:")
	if err = showVersion(thisExecPath); err != nil {
		return caddy.ExitCodeFailedStartup, fmt.Errorf("download succeeded, but unable to execute 'caddy version': %v", err)
	}
	fmt.Println()

	// 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) {

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Run 'caddy version' manually to confirm the installed binary works; if it does, the failure was environmental
  2. Re-run the upgrade command
  3. Disable/reconfigure antivirus real-time scanning for the caddy executable path
  4. If in a container, raise the process/PID limit or upgrade outside the container
Defensive patterns

Strategy: validation

Validate before calling

caddy version   # run once manually; if this works, a failed in-upgrade check was environmental

Prevention

When it happens

Trigger: Intermittent exec failure (AV scanning the file between runs), the binary exiting non-zero for 'version' specifically, or resource exhaustion preventing process spawn (fork failure, PID limits in containers).

Common situations: Antivirus/EDR on Windows intercepting repeated executions of a freshly written file; a hardened container hitting process limits during upgrade; rarely, a genuinely broken build.

Related errors


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