{"record":{"id":"c92eeff6a21e18c6","repo":"caddyserver/caddy","slug":"cannot-auto-upgrade-when-go-module-has-been-replac","errorCode":null,"errorMessage":"cannot auto-upgrade when Go module has been replaced: %s => %s","messagePattern":"cannot auto-upgrade when Go module has been replaced: (.+?) => (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/packagesfuncs.go","lineNumber":311,"sourceCode":"\t\t\tError      struct {\n\t\t\t\tMessage string `json:\"message\"`\n\t\t\t\tID      string `json:\"id\"`\n\t\t\t} `json:\"error\"`\n\t\t}\n\t\terr2 := json.NewDecoder(resp.Body).Decode(&details)\n\t\tif err2 != nil {\n\t\t\treturn nil, fmt.Errorf(\"download and error decoding failed: HTTP %d: %v\", resp.StatusCode, err2)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"download failed: HTTP %d: %s (id=%s)\", resp.StatusCode, details.Error.Message, details.Error.ID)\n\t}\n\treturn resp, nil\n}\n\nfunc getPluginPackages(modules []moduleInfo) (map[string]pluginPackage, error) {\n\tpluginPkgs := make(map[string]pluginPackage)\n\tfor _, mod := range modules {\n\t\tif mod.goModule.Replace != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot auto-upgrade when Go module has been replaced: %s => %s\",\n\t\t\t\tmod.goModule.Path, mod.goModule.Replace.Path)\n\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)","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/cmd/packagesfuncs.go#L293-L329","documentation":"getPluginPackages() refuses to proceed when any compiled-in plugin's Go module has a Replace directive in the go.mod used to build the binary. The build API constructs binaries from published module versions, so a locally-replaced dependency cannot be reproduced server-side; auto-upgrade would silently drop the replacement.","triggerScenarios":"Building caddy with xcaddy from a checkout whose go.mod (or a dependency's go.mod) contains 'replace' directives — e.g. developing a plugin locally with 'replace github.com/foo/bar => ../bar', or using a fork pinned via replace.","commonSituations":"Plugin developers testing a local build with xcaddy --with github.com/me/myplugin=/path/to/local (which adds a replace), then running 'caddy upgrade' on that binary; teams pinning forks of dependencies via replace in a custom build.","solutions":["Do not use 'caddy upgrade' on development builds — rebuild with xcaddy including the local replacement instead","Remove the replace directive and depend on a published version of the module, then upgrade normally","If the replacement is permanent, treat the binary as a custom build and manage upgrades through your own build pipeline (xcaddy build --with ...)"],"exampleFix":"# before\n# go.mod of your custom build:\n#   require github.com/foo/bar v0.0.0\n#   replace github.com/foo/bar => ../bar\ncaddy upgrade  # error: cannot auto-upgrade when Go module has been replaced\n\n# after\nxcaddy build --with github.com/foo/bar=../bar   # rebuild with the replacement explicitly","handlingStrategy":"validation","validationCode":"go version -m \"$(command -v caddy)\" | grep -i '=> ' && echo 'has replace directives: do NOT auto-upgrade; rebuild with xcaddy'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never run 'caddy upgrade' on xcaddy development builds using local --with paths","Publish modules to a versioned source instead of replace directives for production builds","Standardize on xcaddy build --with ... in CI for binaries with replaces"],"tags":["upgrade","go-modules","xcaddy","plugins"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}