ErrLookupBackground articles › mkdir permission denied (EACCES): failed to create directory errors explained

mkdir permission denied (EACCES): failed to create directory errors explained

"mkdir: permission denied" and messages like "failed to create directory" mean a library called mkdir() or an equivalent (os.MkdirAll, create_dir_all, FileHelper::createDirectory, mkdirs) and the operating system refused to create the directory. You meet this error at startup or first write: a tool or service tries to create its state, cache, runtime, or output directory and hits a filesystem-level refusal — permissions, a regular file occupying the path, a read-only mount, or a full disk.

Distilled from 111 documented records across 32 repositories.

Background

This family is produced at the OS/filesystem layer, not by library logic. Every record traces back to a single syscall family: PHP's mkdir(), Go's os.MkdirAll, Rust's std::fs::create_dir_all, Java's File.mkdirs, or Node's mkdirSync. When the kernel returns EACCES, ENOTDIR, EROFS, ENOSPC, or a similar errno, the library wraps it with its own message naming the path — "Failed to create directory \"{$path}\"" in Yii, "failed to create tmp directory: %w" in PentAGI, "create main directory: %w" in Pulumi — and aborts. The wrapped errno inside the message is usually the real diagnosis; the outer text only tells you which directory the library wanted.

Libraries differ mainly in when they call mkdir and how fatal the failure is. Some do it once at startup (Fluentd's root_dir, containerd's volatile container root, caveman's runtime and socket directories), so the whole process refuses to boot. Others do it per-operation: Pulumi's SDK generation, crush's MultiEdit parent-directory creation, waveterm's dated backup directories, or Hadoop's lazy-persist eviction, where each write or copy fails until the directory exists. Recursive helpers (MkdirAll, create_dir_all, mkdir_p) create missing parents as they go, while non-recursive calls (PHP's default mkdir in Leantime and October CMS, Gradle's final mkdirs fallback) fail if an intermediate component is missing. A recurring subtlety: several implementations (Yii's is_dir re-check after issue #9288, containerd's snapshot rollback, Gradle's isDirectory follow-up) re-check whether the directory appeared anyway, to tolerate races where a concurrent process created it between the failed mkdir and the check.

From the caller's side the failure usually looks identical across languages: a wrapped *fs.PathError in Go, an io::Error in Rust, an Errno exception in Ruby, or an ErrorException in PHP (which only reaches a catch block if an error handler converts mkdir's E_WARNING, as Yii's does). Because the underlying cause is environmental, the fix is almost never in code: it is chown/chmod on the parent, removing a regular file that shadows the intended directory, remounting a read-only volume read-write, freeing disk space, or adjusting SELinux/AppArmor or open_basedir policy.

Common causes

What usually fixes it

Documented occurrences

…and 91 more across the corpus — use search.

Honest provenance: generated on 2026-09-02 from AI-assisted analysis of the linked records. See how records are made.