apache/pulsar · error · IOException

${dir} could not be created

Error message

${dir} could not be created

What it means

In ensureDirectoryExistAndCanReadAndWrite, when the target directory does not exist the code calls File.mkdirs(); if that returns false (and the directory still does not exist) it throws IOException '<abs path> could not be created'. mkdirs fails when a parent is not writable, the path is a dangling symlink, or an OS-level error (permissions, disk full, name too long) prevents creation.

Source

Thrown at pulsar-common/src/main/java/org/apache/pulsar/common/nar/FileUtils.java:85

            while (read > -1) {
                digest.update(buffer, 0, read);
                read = inputStream.read(buffer);
            }

            return digest.digest();
        } catch (NoSuchAlgorithmException nsae) {
            throw new IllegalArgumentException(nsae);
        }
    }

    public static void ensureDirectoryExistAndCanReadAndWrite(final File dir) throws IOException {
        if (dir.exists() && !dir.isDirectory()) {
            throw new IOException(dir.getAbsolutePath() + " is not a directory");
        } else if (!dir.exists()) {
            final boolean made = dir.mkdirs();
            if (!made) {
                throw new IOException(dir.getAbsolutePath() + " could not be created");
            }
        }
        if (!(dir.canRead() && dir.canWrite())) {
            throw new IOException(dir.getAbsolutePath() + " directory does not have read/write privilege");
        }
    }

    public static void ensureDirectoryExistAndCanRead(final File dir) throws IOException {
        if (dir.exists() && !dir.isDirectory()) {
            throw new IOException(dir.getAbsolutePath() + " is not a directory");
        } else if (!dir.exists()) {
            final boolean made = dir.mkdirs();
            if (!made) {
                throw new IOException(dir.getAbsolutePath() + " could not be created");
            }
        }
        if (!dir.canRead()) {
            throw new IOException(dir.getAbsolutePath() + " directory does not have read privilege");

View on GitHub (pinned to 820761864e)

Solutions

  1. Run mkdir -p on the path manually as the service user to reveal the OS error.
  2. Grant the process user write permission on the parent directory (chown/chmod).
  3. Point the configuration at a writable location (e.g. under the process's home or a writable volume).
  4. Check for a dangling symlink at the path and remove it.

Example fix

// before (service user cannot write /var/run)
File dir = new File("/var/run/pulsar/nar");
FileUtils.ensureDirectoryExistAndCanReadAndWrite(dir);
// after
File dir = new File("/home/pulsar/run/nar"); // writable location
FileUtils.ensureDirectoryExistAndCanReadAndWrite(dir);
Defensive patterns

Strategy: try-catch

Validate before calling

File parent = dir.getParentFile();
if (parent != null && !parent.canWrite() && !dir.exists()) {
    throw new IllegalStateException("Parent not writable: " + parent);
}

Try / catch

try {
    FileUtils.ensureDirectoryExistAndCanReadAndWrite(dir);
} catch (IOException e) {
    if (e.getMessage().contains("could not be created")) {
        // surface OS detail: attempt mkdirs yourself and log errno/permission state
        log.error("Cannot create {}: parent={}, canWrite={}", dir, dir.getParentFile(),
            dir.getParentFile() != null && dir.getParentFile().canWrite());
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling ensureDirectoryExistAndCanReadAndWrite on a non-existent path whose parent chain cannot be created by the current user, e.g. /var/lib/pulsar-nar under a root-only parent.

Common situations: See trigger scenarios.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/1165ff5a650521f9. Report an issue: GitHub.