gohugoio/hugo · error
failed to download modules
Error message
failed to download modules: %w
What it means
From the downloadModules closure inside listGoMods: a bare `go mod download` (no -json, no explicit modules) exited non-zero, so Hugo aborts the entire module graph load. This is the bulk pre-fetch that precedes `go list`, so any failure to fetch the module set surfaces here wrapped over the raw go error.
Solutions
- Run `hugo mod tidy` (or `go mod download`) in the project to surface and fix the underlying go error, then rebuild.
- For private repos set GOPRIVATE and ensure the VCS credentials/SSH config work: `go env -w GOPRIVATE=github.com/yourorg/*`.
- If go.sum is stale/corrupt, delete go.sum and regenerate with `hugo mod tidy`.
- Verify network egress to proxy.golang.org (or your GOPROXY mirror) and that GOFLAGS is not pinned to -mod=vendor/-mod=readonly incorrectly.
Example fix
// before: cold cache + private module, download fails // after: tidy regenerates sums and pulls modules hugo mod tidy hugo
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: bulk download must succeed before Hugo runs
func ensureModulesDownloaded(projectDir string) error {
cmd := exec.Command("go", "mod", "download")
cmd.Dir = projectDir
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("go mod download: %s", out)
}
return nil
} Type guard
null
Try / catch
null
Prevention
- Run `hugo mod tidy` in CI before the build step.
- Set GOPRIVATE/GOPROXY consistently across dev and CI.
- Commit a correct go.sum and avoid GOFLAGS=-mod=readonly unless vendored.
- Pre-warm caches in Docker builds.
When it happens
Trigger: Any project with at least one module import (moduleConfig.hasModuleImport() true and GoModulesFilename set) where `go mod download` fails — network, auth, sum, or version-resolution errors during the initial bulk download.
Common situations: First build on a new machine with cold module cache, private modules without GOPRIVATE, broken go.sum after a dependency yanked a version, proxy outage, or GOFLAGS=-mod=readonly blocking required downloads.
Related errors
- failed to download module
- failed to download module
- failed to decode module download result
- failed to decode modules list
- failed to list modules
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/fb7275f6f82d7878.
Report an issue: GitHub.
Appendix: source
Thrown at modules/client.go:511
}
defer f.Close()
// Read just one entry to check if directory is non-empty.
_, err = f.Readdirnames(1)
return err == nil
}
func (c *Client) listGoMods() (goModules, error) {
if c.GoModulesFilename == "" || !c.moduleConfig.hasModuleImport() {
return nil, nil
}
downloadModules := func(modules ...string) error {
args := []string{"mod", "download"}
args = append(args, modules...)
out := io.Discard
err := c.runGo(context.Background(), out, args...)
if err != nil {
return fmt.Errorf("failed to download modules: %w", err)
}
return nil
}
if err := downloadModules(); err != nil {
return nil, err
}
listAndDecodeModules := func(handle func(m *goModule) error, modules ...string) error {
b := &bytes.Buffer{}
args := []string{"list", "-m", "-json"}
if len(modules) > 0 {
args = append(args, modules...)
} else {
args = append(args, "all")
}
err := c.runGo(context.Background(), b, args...)
if err != nil {View on GitHub (pinned to 52c9bd7908)