gohugoio/hugo · error

failed to init mount %q %d: %w

Error message

failed to init mount %q %d: %w

What it means

Hugo (modules/config.go:162) returns this while building the default component mounts (content, layouts, static, etc.) for a module. When a directory config like contentDir is set per-language, Hugo creates one mount per language and calls Mount.init() to validate/normalize it; if that validation fails, the error is wrapped with the language code (%q) and component index (%d).

Source

Thrown at modules/config.go:162

					Matrix: sitesmatrix.StringSlices{
						Languages: []string{l.Lang},
					},
				}
			}

			// Static mounts are a little special.
			if component == files.ComponentFolderStatic {
				staticDirs := cfg.StaticDirs()
				for _, dir := range staticDirs {
					mounts = append(mounts, Mount{Sites: sites, Source: dir, Target: component})
				}
				continue
			}

			if dir != "" {
				mnt := Mount{Source: dir, Target: component, Sites: sites}
				if err := mnt.init(logger); err != nil {
					return fmt.Errorf("failed to init mount %q %d: %w", lang, i, err)
				}
				mounts = append(mounts, mnt)
			}
		}
	}

	moda.mounts = append(moda.mounts, mounts...)

	moda.mounts = filterDuplicateMounts(moda.mounts)

	return nil
}

// DecodeConfig creates a modules Config from a given Hugo configuration.
func DecodeConfig(logger logg.Logger, cfg config.Provider) (Config, error) {
	return decodeConfig(logger, cfg, nil)
}

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Look at the wrapped inner error — it names the actual mount problem (usually the source path).
  2. Make the offending dir setting (contentDir, staticDir, etc., possibly under languages.<lang>) a relative path inside the project, not absolute or containing ..
  3. If per-language dirs are involved, verify each language's dir settings individually.
  4. Prefer explicit [[module.mounts]] entries over legacy dir settings for complex layouts.

Example fix

# before (hugo.toml)
[languages.fr]
contentDir = "/home/me/other/content-fr"
# after
[languages.fr]
contentDir = "content-fr"
Defensive patterns

Strategy: validation

Validate before calling

// Validate each module's mounts before loading config
for i, m := range modCfg.Mounts {
    if strings.TrimSpace(m.Source) == "" || strings.TrimSpace(m.Target) == "" {
        return fmt.Errorf("mount %d: source and target must be set", i)
    }
    if !validTargetPrefix(m.Target) { // content, layouts, static, assets, data, i18n, archetypes
        return fmt.Errorf("mount %d: target %q must start with a known component folder", i, m.Target)
    }
}

Try / catch

if err := client.Init(); err != nil {
    var pe *modules.PathError
    // fall back to string inspection since error is wrapped with %w
    if strings.Contains(err.Error(), "failed to init mount") {
        log.Fatalf("check [module.mounts] in config: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Runs during config decoding when Hugo synthesizes mounts from legacy dir settings (contentDir, layoutDir, staticDir, i18nDir, archetypeDir, assetDir, dataDir), including per-language variants such as languages.en.contentDir. Mount.init() rejects invalid mount definitions, e.g. an absolute or traversal source path or an otherwise malformed source/target.

Common situations: Multilingual sites setting contentDir/staticDir per language to an absolute path or a path outside the project; migrating old configs where dir settings point at invalid locations; typos in per-language directory settings.

Related errors


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