gohugoio/hugo · error
%q must resolve to an absolute directory
Error message
%q must resolve to an absolute directory
What it means
Returned by filecache.DecodeConfig after placeholder resolution when a cache directory that is not the resource dir does not compile to an absolute filesystem path, and Hugo is running on a real OS filesystem. Because Hugo performs cache eviction (deletes files) in these directories, it insists on unambiguous absolute paths to avoid operating relative to an unpredictable working directory.
Source
Thrown at cache/filecache/filecache_config.go:278
if err != nil {
return c, err
}
if isResource {
v.IsResourceDir = true
}
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)View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Use an absolute path for the cache dir, or a placeholder that resolves absolutely, e.g. `dir = ":cacheDir/images"`.
- Set a valid top-level `cacheDir` (or HUGO_CACHEDIR env var) so :cacheDir resolves to an absolute directory.
- For project-local resource caching use `:resourceDir`, which is exempt from this check.
Example fix
# before [caches.images] dir = "cache/images" # after [caches.images] dir = ":cacheDir/images"
Defensive patterns
Strategy: validation
Validate before calling
if !filepath.IsAbs(resolvedDir) {
return fmt.Errorf("cache dir %q must resolve to an absolute path", resolvedDir)
} Prevention
- Start cache dirs with :cacheDir or :resourceDir so they always resolve absolute
- Avoid bare relative paths like "cache/images" in caches.*.dir
- Verify HUGO_CACHEDIR / cacheDir itself is an absolute path when set via env
When it happens
Trigger: A caches.<name>.dir set to a relative path like `cache/images` or `./mycache` (without :cacheDir/:resourceDir/:project placeholders producing an absolute root); only enforced when the fs is afero.OsFs, so in-memory test filesystems skip it.
Common situations: Users writing relative cache dirs expecting them to be project-relative, CI configs that hardcode `tmp/cache`, or a :cacheDir placeholder resolving to an empty/relative bcfg.CacheDir because cacheDir was misconfigured.
Related errors
- failed to create file caches from configuration: %w
- %q is a root folder and not allowed as cache dir
- 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/21824f43a0ec4122.json.
Report an issue: GitHub ↗.