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

  1. Check network access to the module proxy or set GOPROXY=direct.
  2. Inspect stderr from Hugo's output for the underlying go error.
  3. Fix GOMODCACHE permissions or clear it (`go clean -modcache`).
  4. 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

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


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/73f6c49a54951c4c.json. Report an issue: GitHub ↗.