{"id":"69c853a89ebde244","repo":"gohugoio/hugo","slug":"failled-to-create-base-cache-directory-s","errorCode":null,"errorMessage":"failled to create base cache directory: %s","messagePattern":"failled to create base cache directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cache/filecache/filecache.go","lineNumber":111,"sourceCode":"\tafero.File\n\tunlock func()\n}\n\nfunc (l *lockedFile) Close() error {\n\tdefer l.unlock()\n\treturn l.File.Close()\n}\n\nfunc (c *Cache) init() error {\n\tif c == nil {\n\t\tpanic(\"cache is nil\")\n\t}\n\n\tc.initOnce.Do(func() {\n\t\tc.isInited = true\n\t\t// Create the base dir if it does not exist.\n\t\tif err := c.Fs.MkdirAll(\"\", 0o777); err != nil && !os.IsExist(err) {\n\t\t\terr = fmt.Errorf(\"failled to create base cache directory: %s\", err)\n\t\t\tc.initErr = err\n\t\t}\n\t})\n\treturn c.initErr\n}\n\n// WriteCloser returns a transactional writer into the cache.\n// It's important that it's closed when done.\nfunc (c *Cache) WriteCloser(id string) (ItemInfo, io.WriteCloser, error) {\n\tif err := c.init(); err != nil {\n\t\treturn ItemInfo{}, nil, err\n\t}\n\n\tid = cleanID(id)\n\tc.entryLocker.Lock(id)\n\n\tinfo := ItemInfo{Name: id}\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/cache/filecache/filecache.go#L93-L129","documentation":"On first use, each file cache lazily creates its base directory via `c.Fs.MkdirAll(\"\", 0o777)` inside a `sync.Once`. If that mkdir fails (and the failure isn't 'already exists'), the error is stored as `initErr` and returned from every subsequent cache operation, so all reads/writes through that cache fail with this message (note the upstream typo 'failled').","triggerScenarios":"Any cache access (`WriteCloser`, `GetOrCreate`, `ReadOrCreate`) whose lazy `init()` runs `MkdirAll` on the cache's base path and gets a permission, read-only-filesystem, or disk-full error — the cache root derives from `cacheDir` config, `HUGO_CACHEDIR`, or the platform default (e.g. `$TMPDIR/hugo_cache`).","commonSituations":"Docker/CI containers running as non-root with `cacheDir` pointing at an unwritable path; read-only root filesystems (Kubernetes `readOnlyRootFilesystem`); Netlify/Vercel builds with unusual `HUGO_CACHEDIR`; a cache path that collides with an existing regular file.","solutions":["Point the cache at a writable location: set `HUGO_CACHEDIR=/tmp/hugo_cache` or `cacheDir` in config to a directory the build user can create.","Fix permissions/ownership on the existing cache root (`chown`/`chmod` the directory).","In containers, mount a writable volume for the cache dir or run the build with a writable `$TMPDIR`."],"exampleFix":"# before (CI container, read-only home)\nhugo --minify\n# after\nexport HUGO_CACHEDIR=/tmp/hugo_cache\nhugo --minify","handlingStrategy":"validation","validationCode":"# Verify the configured cache directory's parent is writable:\nCACHE=${HUGO_CACHEDIR:-$(hugo config | sed -n 's/^cachedir *= *//p')}\nmkdir -p \"$CACHE\" && test -w \"$CACHE\"","typeGuard":null,"tryCatchPattern":"if err := build(); err != nil {\n    if strings.Contains(err.Error(), \"create base cache directory\") {\n        log.Println(\"set HUGO_CACHEDIR to a writable path\")\n    }\n    return err\n}","preventionTips":["Explicitly set HUGO_CACHEDIR (or caches config) to a directory the build user owns","In containers/read-only filesystems, mount a writable volume for the cache","Don't point cacheDir at root-owned system paths","Pre-create the cache dir in CI images"],"tags":["hugo","filecache","permissions","environment"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}