prestodb/presto · error · IOException

File already exists:

Error message

File already exists:

What it means

create(path, ..., overwrite=false) throws IOException if an object already exists at the target key. S3 has no atomic create-new semantics, so the connector explicitly checks exists(path) first and refuses to clobber without overwrite=true.

Source

Thrown at presto-hive/src/main/java/com/facebook/presto/hive/s3/PrestoS3FileSystem.java:433

        }
        return (length != null) ? Long.parseLong(length) : metadata.getContentLength();
    }

    @Override
    public FSDataInputStream open(Path path, int bufferSize)
    {
        return new FSDataInputStream(
                new BufferedFSInputStream(
                        new PrestoS3InputStream(s3, getBucketName(uri), path, maxAttempts, maxBackoffTime, maxRetryTime),
                        bufferSize));
    }

    @Override
    public FSDataOutputStream create(Path path, FsPermission permission, boolean overwrite, int bufferSize, short replication, long blockSize, Progressable progress)
            throws IOException
    {
        if ((!overwrite) && exists(path)) {
            throw new IOException("File already exists:" + path);
        }

        if (!stagingDirectory.exists()) {
            createDirectories(stagingDirectory.toPath());
        }
        if (!stagingDirectory.isDirectory()) {
            throw new IOException("Configured staging path is not a directory: " + stagingDirectory);
        }
        File tempFile = createTempFile(stagingDirectory.toPath(), "presto-s3-", ".tmp").toFile();

        String key = keyFromPath(qualifiedPath(path));
        return new FSDataOutputStream(
                new PrestoS3OutputStream(s3,
                        getBucketName(uri),
                        key,
                        tempFile,
                        sseEnabled,
                        sseType,

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Pass overwrite=true if replacement is intended (matches 'INSERT OVERWRITE' semantics).
  2. Delete the existing object first, or write to a unique temp key and rename.
  3. Ensure downstream consumers clean up prior output before reruns.
  4. Use unique staging keys (timestamp/uuid) per task attempt.

Example fix

// before
FSDataOutputStream out = fs.create(path, permission, false, bufferSize, replication, blockSize, progress);
// after
FSDataOutputStream out = fs.create(path, permission, true, bufferSize, replication, blockSize, progress);
// or check first:
if (fs.exists(path) && !allowOverwrite) throw new IllegalStateException("refusing to overwrite " + path);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!overwrite && fs.exists(path)) {
    throw new IllegalStateException("target exists; enable overwrite or pick a new key: " + path);
}

Type guard

null

Try / catch

try {
    out = fs.create(path, permission, overwrite, bufferSize, replication, blockSize, progress);
} catch (IOException e) {
    if (e.getMessage().startsWith("File already exists:")) {
        // use overwrite=true or write to a unique temp key
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling FileSystem.create with overwrite=false on a path that already has an object; two writers targeting the same key where the second uses overwrite=false.

Common situations: Job retries re-creating output files; Hive insert into an existing unpartitioned table location; concurrent tasks writing the same temp key; leftover files from a previous failed run.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/442fb775f34d420e. Report an issue: GitHub.