gohugoio/hugo · error
module %q not found
Error message
module %q not found
What it means
In `collector.add` (modules/collect.go:287), when an import has an explicit version query (e.g. `path@v1.2.0`), Hugo calls `downloadModuleVersion`; if that returns no module and no error, Hugo reports `module %q not found`. It means the Go toolchain could not produce a module matching that path at the requested version.
Source
Thrown at modules/collect.go:287
if moduleDir == "" {
if requestedVersionQuery == "" {
mod = c.gomods.GetByPath(modulePath)
if mod != nil {
moduleDir = mod.Dir
}
}
if moduleDir == "" {
if isProbablyModule(modulePath) {
if requestedVersionQuery != "" {
var err error
mod, err = c.downloadModuleVersion(modulePath, requestedVersionQuery)
if err != nil {
return nil, err
}
if mod == nil {
return nil, fmt.Errorf("module %q not found", modulePath)
}
moduleDir = mod.Dir
versionMod = mod.Version
} else if c.GoModulesFilename != "" {
// See https://golang.org/ref/mod#version-queries
// This will select the latest release-version (not beta etc.).
const versionQuery = "upgrade"
// Try to "go get" it and reload the module configuration.
// Note that we cannot use c.Get for this, as that may
// trigger a new module collection and potentially create a infinite loop.
if err := c.get(fmt.Sprintf("%s@%s", modulePath, versionQuery)); err != nil {
return nil, err
}
if err := c.loadModules(); err != nil {
return nil, err
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Verify the version exists: `go list -m -versions <modulepath>` or check the repo's tags.
- For major versions ≥2, use the `/v2` (etc.) suffixed module path.
- Remove the version pin to let Hugo select the latest release, then re-pin to a real tag.
- If the tag is brand new, retry with `GOPROXY=direct` to bypass a stale proxy cache.
Example fix
# before [[module.imports]] path = "github.com/org/theme" version = "v2.0.0" # module path for v2 is theme/v2 # after [[module.imports]] path = "github.com/org/theme/v2" version = "v2.0.0"
Defensive patterns
Strategy: validation
Validate before calling
// Check every configured import resolves: entries in config `module.imports`
// must appear in go.mod or exist on disk
for _, imp := range cfg.Imports {
if !knownModule(imp.Path) { /* fix config or run hugo mod get */ }
} Try / catch
if err := build(); err != nil {
if strings.Contains(err.Error(), "not found") {
// config imports a module absent from go.mod / module cache
}
return err
} Prevention
- Keep `module.imports` in the site config in sync with go.mod
- After removing a theme/module from config, run `hugo mod tidy`
- Spell module paths exactly (case-sensitive) as published
When it happens
Trigger: An import with `version` set in module config (or a `path@version` reference) where `go` downloads nothing for that path/version combination — nonexistent tag, wrong module path casing, or a version query matching no release.
Common situations: Pinning a theme to a tag that was deleted or never pushed; requesting `v2.x` of a module whose go.mod path lacks the `/v2` suffix; typos in the path; proxy caches missing a very fresh tag.
Related errors
- go command failed: %s
- failed to execute 'go %v': %s %T
- invalid module path %q; must be relative to themesDir when d
- ErrNotExist
- %q not found
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/280a920c7eeb0599.json.
Report an issue: GitHub ↗.