apache/druid · error · SegmentLoadingException

Unable to create marker file for

Error message

Unable to create marker file for [%s]

What it means

Thrown when FileUtils.mkdirp(storageDir) or downloadStartMarker.createNewFile() throws an IOException while preparing the segment's storage directory before download. The wrap preserves the IO cause; the marker file could not be created, so the download cannot be safely tracked.

Solutions

  1. Fix filesystem permissions on the cache location so the Druid process can mkdir and create files (chown/chmod).
  2. Check disk space and inode availability on the cache volume (df -h, df -i).
  3. Verify the location path is a writable directory, not a file or a read-only mount.
  4. Remove any conflicting path at the storageDir location and retry the load.

Example fix

// before: cache dir not writable by druid user
// drwx------ root root /var/druid/segment-cache
// after
chown -R druid:druid /var/druid/segment-cache
chmod -R u+rwX /var/druid/segment-cache
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight: location must be a writable directory with free space
if (!Files.isDirectory(loc) || !Files.isWritable(loc)) throw new IllegalStateException("bad cache location: " + loc);

Try / catch

try { loadSegment(segment); } catch (SegmentLoadingException e) { if (e.getCause() instanceof IOException io) { log.error("marker mkdir/create failed: %s", io.getMessage()); } }

Prevention

When it happens

Trigger: IOException from creating the storage directory or marker file — permission denied on the cache path, disk full, read-only filesystem, or path exists as a non-directory.

Common situations: Cache location owned by a different user; volume mounted read-only after hardware failure; location path clobbered by a file instead of directory; ENOSPC on the cache volume.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/4e5a788e39ecb99a. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/segment/loading/SegmentLocalCacheManager.java:2427

        throws SegmentLoadingException
    {
      // We use a marker to prevent the case where a segment is downloaded, but before the download completes,
      // the parent directories of the segment are removed
      final File downloadStartMarker = new File(storageDir, DOWNLOAD_START_MARKER_FILE_NAME);
      try {
        FileUtils.mkdirp(storageDir);

        if (!downloadStartMarker.createNewFile()) {
          throw new SegmentLoadingException("Was not able to create new download marker for [%s]", storageDir);
        }
        loadInLocation(segment, storageDir);

        if (!downloadStartMarker.delete()) {
          throw new SegmentLoadingException("Unable to remove marker file for [%s]", storageDir);
        }
      }
      catch (IOException e) {
        throw new SegmentLoadingException(e, "Unable to create marker file for [%s]", storageDir);
      }
    }

    @GuardedBy("entryLock")
    private void loadInLocation(final DataSegment segment, final File storageDir)
        throws SegmentLoadingException
    {
      // LoadSpec isn't materialized until here so that any system can interpret Segment without having to have all the
      // LoadSpec dependencies.
      final LoadSpec loadSpec = jsonMapper.convertValue(segment.getLoadSpec(), LoadSpec.class);
      final LoadSpec.LoadSpecResult result = loadSpec.loadSegment(storageDir);
      if (result.getSize() != segment.getSize()) {
        log.warn(
            "Segment [%s] is different than expected size. Expected [%d] found [%d]",
            segment.getId(),
            segment.getSize(),
            result.getSize()
        );

View on GitHub (pinned to 9b90983fd2)