gohugoio/hugo · error

failed to download modules: %w

Error message

failed to download modules: %w

What it means

Returned by listGoMods' downloadModules helper when the bulk `go mod download` (all modules in go.mod) fails before Hugo lists modules. Hugo needs all imports fetched into the module cache before it can resolve mounts and themes, so a failure here aborts the module graph build.

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 8a468df065)

Solutions

  1. Run `hugo mod tidy` to sync go.mod/go.sum.
  2. Check connectivity to GOPROXY, or set GOPROXY=direct / a mirror.
  3. For private modules, configure GOPRIVATE and credentials.
  4. Use `hugo mod vendor` so builds don't need network.

Example fix

# before
hugo build   # fails offline
# after
hugo mod vendor
hugo build   # uses _vendor, no network
Defensive patterns

Strategy: retry

Try / catch

if err := client.Download(); err != nil {
    if isTransient(err) {
        // bounded retry with backoff for bulk download
    } else {
        return fmt.Errorf("module download failed; run 'hugo mod verify' or clear cache with 'hugo mod clean': %w", err)
    }
}

Prevention

When it happens

Trigger: Any `hugo` build/serve on a module-enabled site where `go mod download` exits non-zero: unreachable proxy, missing go.sum entries, checksum mismatch against sum.golang.org, or a module in go.mod that no longer resolves.

Common situations: Fresh clone without network access, CI runners behind proxies, go.sum out of sync after hand-editing go.mod, upstream theme repo deleted or retagged.

Related errors


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