{"record":{"id":"50d5d9b1e1849f07","repo":"caddyserver/caddy","slug":"unable-to-download-file-v","errorCode":null,"errorMessage":"unable to download file: %v","messagePattern":"unable to download file: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/packagesfuncs.go","lineNumber":331,"sourceCode":"\t\t}\n\t\tpluginPkgs[mod.goModule.Path] = pluginPackage{Version: mod.goModule.Version, Path: mod.goModule.Path}\n\t}\n\treturn pluginPkgs, nil\n}\n\nfunc writeCaddyBinary(path string, body *io.ReadCloser, fileInfo os.FileInfo) error {\n\tl := caddy.Log()\n\tdestFile, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, fileInfo.Mode())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to open destination file: %v\", err)\n\t}\n\tdefer destFile.Close()\n\n\tl.Info(\"downloading binary\", zap.String(\"destination\", path))\n\n\t_, err = io.Copy(destFile, *body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"unable to download file: %v\", err)\n\t}\n\n\terr = destFile.Sync()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"syncing downloaded file to device: %v\", err)\n\t}\n\n\treturn nil\n}\n\nconst downloadPath = \"https://caddyserver.com/api/download\"\n\ntype pluginPackage struct {\n\tVersion string\n\tPath    string\n}\n\nfunc (p pluginPackage) String() string {","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/packagesfuncs.go#L313-L349","documentation":"io.Copy from the HTTP response body to the destination file failed mid-stream. The connection was established and the status was OK, but the transfer broke partway — network reset, proxy timeout, or the server closing the connection. The deferred restore returns the original binary, so this is recoverable by retrying.","triggerScenarios":"Long download interrupted by connection reset; idle-timeout on a proxy or NAT gateway killing the stream; flaky Wi-Fi/VPN; server-side connection drop during a slow custom build (builds can take a while before streaming starts).","commonSituations":"Upgrading on an unstable connection; slow plugin compilation causing intermediary load balancers to time out; mobile/tethered networks.","solutions":["Simply retry 'caddy upgrade' — the original binary was restored automatically","If behind a proxy, raise its read/idle timeouts or use a wired/stable connection","Check for packet loss or MTU issues on VPN tunnels","As a fallback, download a matching custom build URL with curl --retry and replace the binary manually"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Retry the upgrade — the original binary is restored automatically on failure","Prefer stable wired/network paths for large downloads; raise proxy idle timeouts","Script upgrades with a retry loop and verify 'caddy version' afterwards"],"tags":["network","download","upgrade","retry"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}