dianping/cat · error · IOException

Fail to create directory(%s)!

Error message

Fail to create directory(%s)!

What it means

LocalReportBucket throws this IOException when the parent directory of the report data file does not exist and File.mkdirs() fails to create it. This happens during local report storage initialization, when the bucket tries to open dataFile and indexFile under m_baseDir for writing. Because the subsequent FileOutputStream calls would also fail, the constructor aborts immediately with the directory path in the message.

Source

Thrown at cat-core/src/main/java/com/dianping/cat/report/LocalReportBucket.java:168

	@Override
	public void initialize(String name, Date timestamp, int index) throws IOException {
		m_baseDir = new File(Cat.getCatHome(), "bucket/report");
		m_writeLock = new ReentrantLock();
		m_readLock = new ReentrantLock();

		String logicalPath = m_pathBuilder.getReportPath(name, timestamp, index);

		File dataFile = new File(m_baseDir, logicalPath);
		File indexFile = new File(m_baseDir, logicalPath + ".idx");

		if (indexFile.exists()) {
			loadIndexes(indexFile);
		}

		final File dir = dataFile.getParentFile();

		if (!dir.exists() && !dir.mkdirs()) {
			throw new IOException(String.format("Fail to create directory(%s)!", dir));
		}

		m_logicalPath = logicalPath;
		m_writeDataFile = new BufferedOutputStream(new FileOutputStream(dataFile, true), 8192);
		m_writeIndexFile = new BufferedOutputStream(new FileOutputStream(indexFile, true), 8192);
		m_writeDataFileLength = dataFile.length();
		m_readDataFile = new RandomAccessFile(dataFile, "r");
	}

	protected void loadIndexes(File indexFile) throws IOException {
		BufferedReader reader = null;
		m_writeLock.lock();
		try {
			reader = new BufferedReader(new FileReader(indexFile));
			StringSplitter splitter = Splitters.by('\t');

			while (true) {
				String line = reader.readLine();

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Check the directory path printed in the message and create it manually (mkdir -p), then verify ownership
  2. Grant write permission to the process user (chown/chmod) on the base dir, e.g. /data/applogs/cat
  3. If running in a container, ensure the log/report volume is mounted writable
  4. Reconfigure the CAT storage base directory to a writable location if the current one is fixed read-only

Example fix

# before
# java process runs as user 'app', /data/applogs/cat owned by root

# after
sudo mkdir -p /data/applogs/cat
sudo chown -R app:app /data/applogs/cat
Defensive patterns

Strategy: validation

Validate before calling

File dir = dataFile.getParentFile();
if (!dir.exists() && !dir.mkdirs()) {
    if (!dir.canWrite() || !dir.getParentFile().canWrite()) {
        throw new IllegalStateException("No write permission for " + dir
            + " — fix ownership or change the CAT base dir");
    }
}

Try / catch

try {
    bucket.initialize(...);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Fail to create directory")) {
        // surface an actionable config error rather than crashing report storage
        logger.error("CAT report dir not writable: " + e.getMessage());
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Initializing LocalReportBucket when the CAT storage base directory cannot be created: no write permission on the parent path, the path exists as a regular file, a read-only filesystem, or disk full. Also when the report path builder returns a path whose parent collides with an existing file, or in containers/servers where the CAT home dir is misconfigured.

Common situations: Running the CAT client/server under a user without write access to /data/applogs/cat or the configured base dir; Docker images where the volume is mounted read-only; a stale file occupying a directory name; SELinux/AppArmor denying mkdir.

Related errors


AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14). Data as JSON: /api/errors/e6abcd77bb333d92. Report an issue: GitHub.