gohugoio/hugo · error
failed to download module
Error message
failed to download module %s@%s: %w
What it means
Sibling of 460, also in downloadModuleVersion, but fired when extractGoModDownloadError returns an empty string — i.e. `go mod download -json` failed but produced no parseable JSON Error field. The wrapped error is the raw go-command failure (usually an exec.ExitError string from stderr). It signals an opaque go-toolchain failure that Hugo could not annotate further.
Solutions
- Reproduce in isolation: run the exact `go mod download -json path@version` from the Hugo working dir and read the raw stderr that Hugo did not parse.
- Upgrade the Go toolchain to a current version (`go version`) since older releases emit non-JSON errors Hugo cannot parse.
- If stderr shows a sum mismatch, run `go mod tidy` / `hugo mod tidy` to refresh go.sum.
- For TLS/proxy HTML errors, fix GOPROXY and network egress, then `go clean -modcache` and retry.
Example fix
// reproduce to see the raw error // (run from your project root) go mod download -json github.com/x/y@v1.2.3 // then act on the stderr shown, e.g. update sums: hugo mod tidy
Defensive patterns
Strategy: validation
Validate before calling
// Probe the exact command Hugo will run and inspect raw stderr
import "os/exec"
func probeDownload(path, version string) error {
cmd := exec.Command("go", "mod", "download", "-json", path+"@"+version)
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
if strings.TrimSpace(stderr.String()) != "" {
return fmt.Errorf("non-json go error: %s", stderr.String())
}
return err
}
return nil
} Type guard
null
Try / catch
// Wrap downloadModuleVersion callers:
// m, err := c.downloadModuleVersion(p, v)
// if err != nil && !strings.Contains(err.Error(), "-json") {
// // likely opaque go failure -> ask user to run go mod download manually
// } Prevention
- Keep Go on a supported, current version.
- Avoid shell rc files that print to stdout when go is invoked.
- CI: pre-warm the module cache so downloads during Hugo are rare.
- Reproduce any opaque failure with the exact `go mod download` before debugging Hugo.
When it happens
Trigger: An explicit-version module import where `go mod download -json path@version` exits non-zero with stderr that is not valid JSON or lacks the Error key — e.g. go binary crash, SIGKILL (OOM), TLS handshake error printed to stderr, or a go version that does not emit JSON errors for certain failure classes.
Common situations: Outdated Go binary (<1.16) producing non-JSON output, proxy returning HTML error pages instead of JSON, network resets mid-stream, go.sum verification failures printed only to stderr, or GOFLAGS/GOENV corruption making the toolchain misbehave.
Related errors
- failed to download module
- failed to download modules
- 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/73f6c49a54951c4c.
Report an issue: GitHub.
Appendix: 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 52c9bd7908)