gohugoio/hugo · warning
failed to prune cache %q: %w
Error message
failed to prune cache %q: %w
What it means
`Caches.Prune` iterates every configured file cache (getjson, getcsv, images, assets, modules, getresource) and removes expired or unused entries; it operates directly on the filesystem. If pruning one cache fails for any reason other than the directory not existing, the loop stops and wraps the failure with the cache's key so you know which cache was being cleaned.
Source
Thrown at cache/filecache/filecache_pruner.go:43
"github.com/spf13/afero"
)
// Prune removes expired and unused items from this cache.
// The last one requires a full build so the cache usage can be tracked.
// Note that we operate directly on the filesystem here, so this is not
// thread safe.
func (c Caches) Prune() (int, error) {
counter := 0
for k, cache := range c {
count, err := cache.Prune(false)
counter += count
if err != nil {
if herrors.IsNotExist(err) {
continue
}
return counter, fmt.Errorf("failed to prune cache %q: %w", k, err)
}
}
return counter, nil
}
// Prune removes expired and unused items from this cache.
// If force is set, everything will be removed not considering expiry time.
func (c *Cache) Prune(force bool) (int, error) {
if c.cfg.entryIsDir {
return c.pruneRootDirs(force)
}
if err := c.init(); err != nil {
return 0, err
}
counter := 0View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Check the cache name in the error and fix permissions on that subdirectory under your cache root (`chown -R` to the build user).
- Stop concurrent Hugo processes sharing the same cache dir before running `--gc`.
- If the cache is corrupted, delete the named cache subdirectory (or the whole cache root) manually and rebuild.
Defensive patterns
Strategy: try-catch
Validate before calling
# Confirm cache subdirs are intact and writable before pruning: find "$HUGO_CACHEDIR" -maxdepth 1 -type d ! -writable
Try / catch
if err := prune(); err != nil {
// %q names the specific cache that failed — often safe to delete it wholesale
log.Printf("prune failed: %v — removing that cache dir manually and continuing", err)
} Prevention
- Run `hugo --gc` from the same user/permissions that created the cache
- If a specific cache repeatedly fails to prune, delete its directory and let Hugo recreate it
- Avoid pruning while another Hugo build is writing to the same cache
- Keep the cache on a local filesystem, not flaky network mounts
When it happens
Trigger: Running `hugo --gc` or `hugo server` with GC enabled: `cache.Prune(false)` on a specific cache returns a non-IsNotExist error — e.g. permission denied deleting an entry, an entry directory locked by another process, or filesystem I/O errors while walking/removing cache files.
Common situations: Cache directories created by a different user (root-built Docker layer, then non-root prune); antivirus or backup tools holding locks on cache files on Windows; NFS/network-mounted cache dirs with flaky delete semantics; two concurrent Hugo builds sharing one cache dir (Prune is documented as not thread safe).
Related errors
- failled to create base cache directory: %s
- failed to save file %q:: %w
- failed to save file %q: %s
- failed to create workingDir: %w
- failed to create file caches from configuration: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/c30b49cd7bdf0d64.json.
Report an issue: GitHub ↗.