gohugoio/hugo · error
failed to download module %s@%s: %w
Error message
failed to download module %s@%s: %w
What it means
Same call site as error 102, but the fallback path: `go mod download -json` failed and no JSON error detail could be extracted from stdout, so Hugo wraps only the process error. Usually indicates the go command failed before producing module-level output (environment or network level failure).
Source
Thrown at modules/client.go:466
if err := json.Unmarshal(b, &cm); err == nil && cm.Dir != "" {
if c.isDirNonEmpty(cm.Dir) {
return &cm, nil
}
}
}
// No valid cache, need to query.
args := []string{"mod", "download", "-json", fmt.Sprintf("%s@%s", path, version)}
b := &bytes.Buffer{}
err := c.runGo(context.Background(), b, args...)
if err != nil {
// The -json flag makes Go output error details as JSON to stdout
// even on failure. Try to extract the error message from the JSON output.
if jsonErr := extractGoModDownloadError(b.Bytes()); jsonErr != "" {
return nil, fmt.Errorf("failed to download module %s@%s: %s: %s", path, version, err, jsonErr)
}
return nil, fmt.Errorf("failed to download module %s@%s: %w", path, version, err)
}
jsonResult := b.Bytes()
m := &goModule{}
if err := json.NewDecoder(bytes.NewReader(jsonResult)).Decode(m); err != nil {
return nil, fmt.Errorf("failed to decode module download result: %w", err)
}
if m.Error != nil {
return nil, errors.New(m.Error.Err)
}
// Cache the successful result if it has a Dir field.
if m.Dir != "" {
_ = c.ccfg.ModuleQueriesCache.SetBytes(cacheKey, jsonResult)
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Check network access to the module proxy or set GOPROXY=direct.
- Inspect stderr from Hugo's output for the underlying go error.
- Fix GOMODCACHE permissions or clear it (`go clean -modcache`).
- Vendor modules (`hugo mod vendor`) for offline/CI builds.
Defensive patterns
Strategy: retry
Try / catch
if err := client.Download(mod); err != nil {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
// transient — retry with backoff
} else {
return err
}
} Prevention
- Use errors.As/errors.Is on the wrapped cause to classify before retrying
- Set GOFLAGS=-mod=mod only when mutation is intended; use vendoring in air-gapped builds so download is never needed
- Pre-verify the version exists via 'go list -m -versions <path>' in diagnostics tooling
When it happens
Trigger: `go mod download -json path@version` exiting non-zero with empty or non-JSON stdout: go binary crash, GOPROXY unreachable, DNS failure, disk full in the module cache, or invalid GOFLAGS.
Common situations: Offline builds/CI without vendoring, misconfigured GOPROXY/GONOSUMDB env vars in CI, module cache permission problems (cache created by a different user, e.g. root in Docker).
Related errors
- failed to download modules: %w
- failed to get %q: %w
- failed to download module %s@%s: %s: %s
- failed to init modules: %w
- failed to decode module download result: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/73f6c49a54951c4c.json.
Report an issue: GitHub ↗.