gohugoio/hugo · error
%q is a root folder and not allowed as cache dir
Error message
%q is a root folder and not allowed as cache dir
What it means
Returned by filecache.DecodeConfig when a cache directory compiles to a filesystem root such as `/` on Unix or `C:\` on Windows (path length 1 after stripping the volume name). Hugo prunes and deletes files inside cache directories, so allowing a root directory could lead to catastrophic deletion; this is an explicit safety guard.
Source
Thrown at cache/filecache/filecache_config.go:283
}
parts[i] = resolved
}
}
dir = path.Join(parts...)
if hadSlash {
dir = "/" + dir
}
v.DirCompiled = filepath.Clean(filepath.FromSlash(dir))
if !v.IsResourceDir {
if isOsFs && !filepath.IsAbs(v.DirCompiled) {
return c, fmt.Errorf("%q must resolve to an absolute directory", v.DirCompiled)
}
// Avoid cache in root, e.g. / (Unix) or c:\ (Windows)
if len(strings.TrimPrefix(v.DirCompiled, filepath.VolumeName(v.DirCompiled))) == 1 {
return c, fmt.Errorf("%q is a root folder and not allowed as cache dir", v.DirCompiled)
}
}
if !strings.HasPrefix(v.DirCompiled, "_gen") {
// We do cache eviction (file removes) and since the user can set
// his/hers own cache directory, we really want to make sure
// we do not delete any files that do not belong to this cache.
// We do add the cache name as the root, but this is an extra safe
// guard. We skip the files inside /resources/_gen/ because
// that would be breaking.
v.DirCompiled = filepath.Join(v.DirCompiled, FilecacheRootDirname, k)
} else {
v.DirCompiled = filepath.Join(v.DirCompiled, k)
}
c[k] = v
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Point the cache dir at a dedicated subdirectory, e.g. `/var/cache/hugo` or `/tmp/hugo_cache`, never the filesystem root.
- Check the top-level cacheDir setting and HUGO_CACHEDIR env var for values like `/`.
- In containers, mount the cache volume at a subpath (e.g. /cache) and set cacheDir to that.
Example fix
# before HUGO_CACHEDIR=/ hugo # after HUGO_CACHEDIR=/var/cache/hugo hugo
Defensive patterns
Strategy: validation
Validate before calling
clean := filepath.Clean(resolvedDir)
if clean == string(os.PathSeparator) || (len(clean) == 3 && clean[1] == ':') { // "/" or "C:\\"
return fmt.Errorf("cache dir %q may not be a filesystem root", clean)
} Prevention
- Never point a cache dir at / or a drive root — Hugo may prune cache dirs and refuses roots as a safety guard
- Always include at least one subdirectory component under the placeholder
- Double-check env-var expansion (an unset var can collapse a path to /)
When it happens
Trigger: caches.<name>.dir set to `/`, `C:\`, or a placeholder chain that collapses to root — e.g. `:cacheDir` when the configured cacheDir is `/`, or `dir = "/.."`-style paths that Clean to `/`.
Common situations: Misconfigured HUGO_CACHEDIR or cacheDir set to `/` in containers, env substitution yielding just a slash, or Docker setups mounting a cache volume at root and pointing Hugo directly at it.
Related errors
- failed to create file caches from configuration: %w
- %q must resolve to an absolute directory
- failed to create workingDir: %w
- no filesystem provided
- no existing content directory configured for this project
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/34cb46e9ea404f0d.json.
Report an issue: GitHub ↗.