apache/iceberg · error · AlreadyExistsException
Location already exists: %s
Error message
Location already exists: %s
What it means
S3OutputFile.create() checks exists() first and throws AlreadyExistsException if an object is already present at the location. Iceberg's FileIO contract: create() fails if the file exists, while createOrOverwrite() silently replaces it.
Source
Thrown at aws/src/main/java/org/apache/iceberg/aws/s3/S3OutputFile.java:66
S3AsyncClient asyncClient,
S3URI uri,
S3FileIOProperties s3FileIOProperties,
MetricsContext metrics) {
super(client, asyncClient, uri, s3FileIOProperties, metrics);
}
/**
* Create an output stream for the specified location if the target object does not exist in S3 at
* the time of invocation.
*
* @return output stream
*/
@Override
public PositionOutputStream create() {
if (!exists()) {
return createOrOverwrite();
} else {
throw new AlreadyExistsException("Location already exists: %s", uri());
}
}
@Override
public PositionOutputStream createOrOverwrite() {
try {
return new S3OutputStream(client(), uri(), s3FileIOProperties(), metrics());
} catch (IOException e) {
throw new UncheckedIOException("Failed to create output stream for location: " + uri(), e);
}
}
@Override
public InputFile toInputFile() {
return new S3InputFile(client(), asyncClient(), uri(), null, s3FileIOProperties(), metrics());
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Use createOrOverwrite() if replacing the existing object is acceptable.
- Choose a unique output path (UUID/timestamp suffix) before calling create().
- Delete the existing object first if it is a stale artifact.
- Add concurrency control (e.g. task attempt paths) so parallel writers do not collide.
Example fix
// before
OutputFile out = io.newOutputFile("s3://bucket/data/file.parquet");
PositionOutputStream s = out.create(); // AlreadyExistsException
// after
OutputFile out = io.newOutputFile("s3://bucket/data/file-" + UUID.randomUUID() + ".parquet");
PositionOutputStream s = out.createOrOverwrite(); Defensive patterns
Strategy: try-catch
Validate before calling
// Java
OutputFile out = io.newOutputFile(path);
if (out.exists()) {
path = path + "-" + UUID.randomUUID();
out = io.newOutputFile(path);
} Try / catch
// Java
try {
os = outFile.create();
} catch (AlreadyExistsException e) {
os = outFile.createOrOverwrite(); // or regenerate a unique path
} Prevention
- Always write to unique, attempt-scoped paths (UUID or task attempt in the name)
- Use createOrOverwrite() when idempotent replacement is intended
- Clean up stale objects from failed writes before retrying the same path
When it happens
Trigger: Calling S3OutputFile.create() when an object already exists at the S3 URI; also produced when create() internally calls exists() and S3 reports the key present (e.g. a leftover object from a failed previous write).
Common situations: Writing a data/manifest file to a path reused after a failed job; two concurrent writers choosing the same path; accidentally passing a directory-like or existing key to create().
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
- Location does not exist: %s
- Failed to create file: %s
- Failed to delete: %s
- %s does not expose configuration properties
- Failed to create S3 analytics accelerator input stream for:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/6306fc937766d91e.
Report an issue: GitHub.