caddyserver/caddy · error
download failed: %v
Error message
download failed: %v
What it means
upgradeBuild failed to obtain a custom build from the download API (https://caddyserver.com/api/download). downloadBuild performs an HTTP GET with os/arch and the package list; this wrapper fires on transport errors ('secure request failed: ...') or HTTP >= 400 responses from the API (bad/unknown module, version that doesn't exist, build server error), with the API's decoded message embedded. Note this mechanism requires internet access to caddyserver.com — builds are produced server-side, not locally.
Source
Thrown at cmd/packagesfuncs.go:158
return caddy.ExitCodeFailedStartup, fmt.Errorf("resolving current executable symlink: %v", err)
}
l.Info("this executable is a symlink", zap.String("source", symSource), zap.String("target", thisExecPath))
}
l.Info("this executable will be replaced", zap.String("path", thisExecPath))
// build the request URL to download this custom build
qs := url.Values{
"os": {runtime.GOOS},
"arch": {runtime.GOARCH},
}
for _, pkgInfo := range pluginPkgs {
qs.Add("p", pkgInfo.String())
}
// initiate the build
resp, err := downloadBuild(qs)
if err != nil {
return caddy.ExitCodeFailedStartup, fmt.Errorf("download failed: %v", err)
}
defer resp.Body.Close()
// back up the current binary, in case something goes wrong we can replace it
backupExecPath := thisExecPath + ".tmp"
l.Info("build acquired; backing up current executable",
zap.String("current_path", thisExecPath),
zap.String("backup_path", backupExecPath))
err = os.Rename(thisExecPath, backupExecPath)
if err != nil {
return caddy.ExitCodeFailedStartup, fmt.Errorf("backing up current binary: %v", err)
}
defer func() {
if err != nil {
err2 := os.Rename(backupExecPath, thisExecPath)
if err2 != nil {
l.Error("restoring original executable failed; will need to be restored manually",
zap.String("backup_path", backupExecPath),View on GitHub (pinned to 50e54ee279)
Solutions
- Read the nested error: 'secure request failed' indicates a network/TLS problem; 'HTTP 4xx/5xx ... message' indicates a bad request — fix the module path/version it names
- Check connectivity: `curl -I 'https://caddyserver.com/api/download?os=linux&arch=amd64'`; fix DNS, egress rules, or proxy env (HTTPS_PROXY) as needed
- For private/unpublishable modules or offline hosts, build locally with xcaddy instead of the download API
- Verify the exact module path and a published version tag exist on the Go module proxy (proxy.golang.org)
Example fix
# before (offline / private module) caddy add-package github.com/corp/private-plugin # download failed: HTTP 400 # after xcaddy build --with github.com/corp/private-plugin
Defensive patterns
Strategy: retry
Validate before calling
curl -fsSI --max-time 10 'https://caddyserver.com/api/download?os=linux&arch=amd64' >/dev/null \ && echo 'download API reachable' \ || echo 'API unreachable; fix network or use xcaddy build --with <module>'
Try / catch
# shell: run upgrade, fall back to xcaddy on network failure if ! caddy upgrade; then echo 'in-place upgrade failed; falling back to xcaddy' >&2 xcaddy build --with github.com/caddy-dns/cloudflare fi
Prevention
- Ensure egress to caddyserver.com (and trusted TLS) on hosts that use upgrade/add-package
- Use xcaddy for offline, proxied, or private-module environments
- Pin plugin versions that exist on proxy.golang.org to avoid HTTP 400 from the build API
When it happens
Trigger: `caddy upgrade`, `caddy add-package`, or `caddy remove-package` with no route to caddyserver.com (offline host, blocked egress, DNS failure, TLS-intercepting proxy); or requesting a module/version the API cannot resolve (typo, yanked version, private repo).
Common situations: Hardened servers and air-gapped environments where the build API is unreachable; corporate proxies whose MITM certificate chain Caddy doesn't trust; adding a plugin from a private repository; caddyserver.com being down or rate-limiting.
Related errors
- unable to enumerate installed plugins: %v
- module name is required
- at least one package name must be specified
- retrieving current executable permission bits: %v
- resolving current executable symlink: %v
AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15).
Data as JSON: /api/errors/8ab6a764ee873ec9.
Report an issue: GitHub.