twigphp/Twig · error · RuntimeException
Unable to create the cache directory
Error message
Unable to create the cache directory (%s).
What it means
FilesystemCache::write() creates the cache directory with @mkdir if it is missing. If mkdir fails (and the directory still doesn't exist afterward), it means filesystem-level permission or path problems, so Twig throws this RuntimeException because compiled templates cannot be stored.
Solutions
- Create the cache directory manually and give the PHP user write access: mkdir -p <dir> && chown www-data:www-data <dir>.
- Verify the cache path in setCache() points to a writable location and is not occupied by a regular file.
- Check for read-only mounts or restricted sandbox filesystems and point the cache at a writable path (e.g. sys_get_temp_dir()).
- If the cache is not needed, disable it (don't set a filesystem cache) in dev.
- Check disk space with df -h.
Example fix
// before
$twig->setCache('/var/cache/twig'); // www-data cannot create /var/cache/twig
// after
$cacheDir = '/var/cache/twig';
if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
if (!is_dir($cacheDir) || !is_writable($cacheDir)) {
$cacheDir = sys_get_temp_dir().'/twig';
}
$twig->setCache($cacheDir); Defensive patterns
Strategy: try-catch
Validate before calling
function ensureCacheDirWritable(string $cacheDir): void {
if (!is_dir($cacheDir)) { @mkdir($cacheDir, 0775, true); }
if (!is_dir($cacheDir) || !is_writable($cacheDir)) {
throw new \RuntimeException("Cache dir not writable: $cacheDir");
}
} Try / catch
try { $twig->render($name, $vars); } catch (\RuntimeException $e) {
if (str_starts_with($e->getMessage(), 'Unable to create the cache directory')) {
$twig->setCache(sys_get_temp_dir().'/twig'); // fallback cache
} else { throw $e; }
} Prevention
- Provision and chown the cache directory during deployment, not at first render.
- Run PHP under a user with write access to the configured cache path.
- Never point setCache() at read-only mounts or paths occupied by files.
- Monitor disk space and filesystem writability in health checks.
When it happens
Trigger: Calling $env->setCache('/path') (FilesystemCache) and then rendering; the dirname of the cache key path cannot be created because a parent directory is missing/unwritable, the filesystem is read-only, or a non-directory file exists at that path. Also triggered when mkdir races and fails and the dir truly is absent.
Common situations: Deployed containers running the PHP process as a non-root user without write access to the cache path; read-only filesystems (Docker images, serverless /var restrictions); typoed cache path like /var/cache/twig where /var/cache/twig is actually a file; disk full.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- The " " directory does not exist (" ").
- Template " " is not defined.
- Unable to find template
- Unknown " " configuration.
- The " " modifier takes exactly one argument (0 given).
AI-assisted analysis of twigphp/Twig@a414c3a491 (2026-09-13).
Data as JSON: /api/errors/e35e0a39dc94519b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Cache/FilesystemCache.php:53
return $this->directory.$hash[0].$hash[1].'/'.$hash.'.php';
}
public function load(string $key): void
{
if (is_file($key)) {
@include_once $key;
}
}
public function write(string $key, string $content): void
{
$dir = \dirname($key);
if (!is_dir($dir)) {
if (false === @mkdir($dir, 0777, true)) {
clearstatcache(true, $dir);
if (!is_dir($dir)) {
throw new \RuntimeException(\sprintf('Unable to create the cache directory (%s).', $dir));
}
}
} elseif (!is_writable($dir)) {
throw new \RuntimeException(\sprintf('Unable to write in the cache directory (%s).', $dir));
}
$tmpFile = tempnam($dir, basename($key));
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $key)) {
@chmod($key, 0666 & ~umask());
if (self::FORCE_BYTECODE_INVALIDATION == ($this->options & self::FORCE_BYTECODE_INVALIDATION)) {
// Compile cached file into bytecode cache
if (\function_exists('opcache_invalidate') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN)) {
@opcache_invalidate($key, true);
} elseif (\function_exists('apc_compile_file')) {
apc_compile_file($key);
}
}View on GitHub (pinned to a414c3a491)