apache/druid · error · org.apache.druid.java.util.common.RE

Cannot delete temp file

Error message

Cannot delete temp file [%s]

What it means

When the returned FileInputStream over the temp chunk file is closed, the connector deletes outFile and throws this RuntimeException if File.delete() returns false. delete() fails when the file cannot be removed, e.g. another open handle on the same file or OS-level restrictions.

Solutions

  1. Ensure every consumer closes its own stream promptly and no handles are leaked
  2. Use a unique temp file per copy so concurrent readers do not share one file
  3. Manually delete the stale temp file after the process stops holding it

Example fix

// ensure prompt close
try (FileInputStream in = connector.getSegment(path)) {
  consume(in);
} // close() deletes the temp file here, no leaked handles
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure no other handles before close
boolean stillOpen = otherReaders.stream().anyMatch(r -> !r.isClosed());

Try / catch

try (FileInputStream in = connector.getSegment(...)) { consume(in); } catch (RuntimeException e) { // delete failed: check for leaked handles, clean up manually }

Prevention

When it happens

Trigger: Closing the stream returned by ChunkingStorageConnector.getSegment/getNextElement when the temp file cannot be deleted — typically because another thread/process still holds the file open, or on some platforms the delete races with a concurrent reader.

Common situations: Multiple consumers sharing one chunk file (a second reader still holds an fd); file locked by indexing/scanning software; NFS exports where unlink semantics misbehave; leftover handles after a leaked stream that was never closed.

Related errors


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

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/storage/remote/ChunkingStorageConnector.java:189

              throw new RE(e, StringUtils.format("Unable to copy [%s] to [%s]", params.getCloudStoragePath(), outFile));
            }

            try {
              AtomicBoolean fileInputStreamClosed = new AtomicBoolean(false);
              return new FileInputStream(outFile)
              {
                @Override
                public void close() throws IOException
                {
                  // close should be idempotent
                  if (fileInputStreamClosed.get()) {
                    return;
                  }
                  fileInputStreamClosed.set(true);
                  super.close();
                  currentReadStartPosition.set(currentReadEndPosition);
                  if (!outFile.delete()) {
                    throw new RE("Cannot delete temp file [%s]", outFile);
                  }
                }

              };
            }
            catch (FileNotFoundException e) {
              throw new RE(e, StringUtils.format("Unable to find temp file [%s]", outFile));
            }
          }
        }
    )
    {
      @Override
      public void close() throws IOException
      {
        isSequenceStreamClosed.set(true);
        super.close();
      }

View on GitHub (pinned to 9b90983fd2)