gohugoio/hugo · error

failed to load modules: %w

Error message

failed to load modules: %w

What it means

Returned when l.loadModules fails — the step that resolves the site's module graph (theme(s), Hugo Modules from [module.imports], their transitive imports and mounts) using the modules client. It wraps errors from Go-module resolution, filesystem mounting, or missing themes/modules, unless IgnoreModuleDoesNotExist is set for commands like `hugo mod init`.

Source

Thrown at config/allconfig/load.go:78

	l := &configLoader{ConfigSourceDescriptor: d, cfg: config.New()}
	// Make sure we always do this, even in error situations,
	// as we have commands (e.g. "hugo mod init") that will
	// use a partial configuration to do its job.
	defer l.deleteMergeStrategies()
	res, _, err := l.loadConfigMain(d)
	if err != nil {
		return nil, fmt.Errorf("failed to load config: %w", err)
	}

	configs, err = fromLoadConfigResult(d.Fs, d.Logger, res)
	if err != nil {
		return nil, fmt.Errorf("failed to create config from result: %w", err)
	}

	moduleConfig, modulesClient, err := l.loadModules(configs, d.IgnoreModuleDoesNotExist)
	if err != nil {
		return nil, fmt.Errorf("failed to load modules: %w", err)
	}

	if len(l.ModulesConfigFiles) > 0 {
		// Config merged in from modules.
		// Re-read the config.
		configs, err = fromLoadConfigResult(d.Fs, d.Logger, res)
		if err != nil {
			return nil, fmt.Errorf("failed to create config from modules config: %w", err)
		}
		if err := configs.transientErr(); err != nil {
			return nil, fmt.Errorf("failed to create config from modules config: %w", err)
		}
		configs.LoadingInfo.ConfigFiles = append(configs.LoadingInfo.ConfigFiles, l.ModulesConfigFiles...)
	} else if err := configs.transientErr(); err != nil {
		return nil, fmt.Errorf("failed to create config: %w", err)
	}

	configs.Modules = moduleConfig.AllModules

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. If the theme is a git submodule, run `git submodule update --init --recursive` so themes/<name> is populated.
  2. For Hugo Modules, ensure Go is installed and run `hugo mod get` / `hugo mod tidy`; check network and GOPRIVATE for private repos.
  3. Verify the theme/module path in config matches the directory or repo path exactly.
  4. Clear a corrupt cache with `hugo mod clean`, or vendor dependencies with `hugo mod vendor` for hermetic builds.

Example fix

# before (CI)
hugo --minify   # themes/ananke empty
# after
git submodule update --init --recursive
hugo --minify
Defensive patterns

Strategy: retry

Validate before calling

// Verify module prerequisites before loading
if _, err := exec.LookPath("go"); err != nil {
    return errors.New("hugo modules require the go binary on PATH")
}
if _, err := os.Stat(filepath.Join(workingDir, "go.mod")); err != nil {
    // module config present but no go.mod → run hugo mod init first
}

Try / catch

conf, err := allconfig.LoadConfig(opts)
if err != nil {
    // module fetches hit the network; retry transient failures a bounded number of times,
    // but treat resolution errors (bad module path/version) as permanent
    if isTransientNetErr(err) { /* bounded retry with backoff */ }
    return err
}

Prevention

When it happens

Trigger: theme = 'x' or [[module.imports]] path pointing at a theme/module that doesn't exist in themes/ or can't be fetched; running module-based sites without Go installed or without network access; a corrupt module cache; go.mod/go.sum inconsistencies; invalid [module.mounts] source paths.

Common situations: Cloning a site without `git submodule update --init` so themes/<name> is empty; CI without Go installed for a Hugo Modules site; private module repos without credentials (GOPRIVATE/netrc); typo in the theme name; offline builds needing `hugo mod vendor`.

Related errors


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