gohugoio/hugo · error

failed to init mount %d: %w

Error message

failed to init mount %d: %w

What it means

Hugo (modules/config.go:233) returns this while decoding the explicit [module.mounts] section of the site config. Each declared mount's Source and Target are cleaned and then validated via Mount.init(); if a mount is invalid the error is wrapped with its zero-based index (%d) in the mounts list.

Source

Thrown at modules/config.go:233

				c.replacementsMap[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
			}
		}

		if c.replacementsMap != nil && c.Imports != nil {
			for i, imp := range c.Imports {
				if newImp, found := c.replacementsMap[imp.Path]; found {
					imp.Path = newImp
					imp.pathProjectReplaced = true
					c.Imports[i] = imp
				}
			}
		}

		for i, mnt := range c.Mounts {
			mnt.Source = filepath.Clean(mnt.Source)
			mnt.Target = filepath.Clean(mnt.Target)
			if err := mnt.init(logger); err != nil {
				return c, fmt.Errorf("failed to init mount %d: %w", i, err)
			}
			c.Mounts[i] = mnt
		}

		if c.Workspace == "" {
			c.Workspace = WorkspaceDisabled
		}
		if c.Workspace != WorkspaceDisabled {
			c.Workspace = filepath.Clean(c.Workspace)
			if !filepath.IsAbs(c.Workspace) {
				workingDir := cfg.GetString("workingDir")
				c.Workspace = filepath.Join(workingDir, c.Workspace)
			}
			if _, err := os.Stat(c.Workspace); err != nil {
				//lint:ignore ST1005 end user message.
				return c, fmt.Errorf("module workspace %q does not exist. Check your module.workspace setting (or HUGO_MODULE_WORKSPACE env var).", c.Workspace)
			}
		}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Count into your [[module.mounts]] list using the index in the message (0-based) to find the bad entry.
  2. Fix its source to a relative in-project path and its target to start with a valid component root like content/, static/, assets/.
  3. Read the wrapped error text for the concrete validation failure.
  4. Run hugo config to confirm the decoded mounts look as intended.

Example fix

# before
[[module.mounts]]
source = "/abs/path/content"
target = "content"
# after
[[module.mounts]]
source = "content"
target = "content"
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check top-level mounts in the project config
for i, m := range cfg.Module.Mounts {
    if m.Source == "" {
        return fmt.Errorf("module.mounts[%d]: missing source", i)
    }
    if filepath.IsAbs(m.Source) {
        return fmt.Errorf("module.mounts[%d]: source must be relative, got %q", i, m.Source)
    }
}

Try / catch

if err := modules.ApplyProjectConfigDefaults(mod, cfgs...); err != nil {
    if strings.Contains(err.Error(), "failed to init mount") {
        return fmt.Errorf("invalid [module.mounts] entry: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: decodeConfig() iterates c.Mounts from the user's module.mounts config and calls mnt.init(logger). A mount with a bad source (e.g. absolute path, path traversal, empty/invalid value) or an invalid target component causes init to fail for that index.

Common situations: Hand-written [[module.mounts]] blocks with an absolute source path, a target that isn't a known component root (content, static, layouts, assets, data, i18n, archetypes), or a lang attribute problem; copy-pasted mounts from other projects with wrong paths.

Related errors


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