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

  1. Use an absolute path for the cache dir, or a placeholder that resolves absolutely, e.g. `dir = ":cacheDir/images"`.
  2. Set a valid top-level `cacheDir` (or HUGO_CACHEDIR env var) so :cacheDir resolves to an absolute directory.
  3. 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

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


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