gohugoio/hugo · error
failed to create cache dir: %w
Error message
failed to create cache dir: %w
What it means
helpers.GetCacheDir resolves Hugo's cache directory (from the `cacheDir` config, HUGO_CACHEDIR, or a default) and creates it with MkdirAll if it doesn't exist. This error wraps the underlying filesystem error when that MkdirAll fails, meaning Hugo cannot set up the directory used for module downloads, image processing cache, and getresource caches.
Source
Thrown at helpers/path.go:253
}
return f, err
}
// GetCacheDir returns a cache dir from the given filesystem and config.
// The dir will be created if it does not exist.
func GetCacheDir(fs afero.Fs, cacheDir string) (string, error) {
cacheDir = cacheDirDefault(cacheDir)
if cacheDir != "" {
exists, err := DirExists(cacheDir, fs)
if err != nil {
return "", err
}
if !exists {
err := fs.MkdirAll(cacheDir, 0o777) // Before umask
if err != nil {
return "", fmt.Errorf("failed to create cache dir: %w", err)
}
}
return cacheDir, nil
}
const hugoCacheBase = "hugo_cache"
// Avoid filling up the home dir with Hugo cache dirs from development.
if !htesting.IsTest {
userCacheDir, err := os.UserCacheDir()
if err == nil {
cacheDir := filepath.Join(userCacheDir, hugoCacheBase)
if err := fs.Mkdir(cacheDir, 0o777); err == nil || os.IsExist(err) {
return cacheDir, nil
}
}
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Check the wrapped error detail (permission denied, read-only file system, not a directory) and point `cacheDir`/HUGO_CACHEDIR at a writable location, e.g. a path under the CI workspace or $HOME.
- In containers, mount a writable volume and set `HUGO_CACHEDIR=/tmp/hugo_cache` (or similar) so cache creation succeeds.
- If a file exists at the cache path, remove or rename it so a directory can be created.
- Fix ownership/permissions on the parent directory (`chown`/`chmod`) if the path itself is correct.
Example fix
# before (CI) hugo --minify # HUGO_CACHEDIR=/var/hugo_cache, not writable by build user # after export HUGO_CACHEDIR=$GITHUB_WORKSPACE/.hugo_cache hugo --minify
Defensive patterns
Strategy: try-catch
Validate before calling
// Verify the cache dir is creatable/writable before invoking Hugo
if err := os.MkdirAll(cacheDir, 0o755); err != nil { log.Fatalf("cacheDir unusable: %v", err) }
f, err := os.CreateTemp(cacheDir, "probe*"); if err == nil { f.Close(); os.Remove(f.Name()) } Try / catch
if err := run(); err != nil {
if errors.Is(err, fs.ErrPermission) || strings.Contains(err.Error(), "failed to create cache dir") {
// point cacheDir at a writable location and retry once
}
} Prevention
- Set `cacheDir` explicitly in config (or HUGO_CACHEDIR) to a directory the build user owns
- In containers/CI, mount or pre-create the cache dir with correct permissions
- Don't point cacheDir at read-only or noexec-mounted filesystems
When it happens
Trigger: MkdirAll on the resolved cache path returns an error: the configured `cacheDir` points into a location the user lacks write permission for, a path component exists as a regular file, the disk is full, or the path is on a read-only mount. Occurs at startup of any hugo build/server command that initializes caches.
Common situations: CI containers running as a non-root user with `cacheDir` or HUGO_CACHEDIR set to a root-owned path like /var/hugo_cache; read-only root filesystems in hardened containers (need a writable volume for the cache); Windows/网络 drives with restricted ACLs; a stale file occupying the configured cache path.
Related errors
- failed to save file %q:: %w
- failed to save file %q: %s
- failed to create workingDir: %w
- failed to open non-content file: %w
- failed to create target directory for %q: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/239e6fbf5e50d6df.json.
Report an issue: GitHub ↗.