apache/iceberg · error · AlreadyExistsException
Location already exists: %s
Error message
Location already exists: %s
What it means
OSSOutputFile.create() first checks whether the target object already exists in OSS and throws AlreadyExistsException if it does. This prevents silently clobbering an existing data/manifest file, matching the FileIO contract that create() must not overwrite.
Source
Thrown at aliyun/src/main/java/org/apache/iceberg/aliyun/oss/OSSOutputFile.java:46
class OSSOutputFile extends BaseOSSFile implements OutputFile {
OSSOutputFile(OSS client, OSSURI uri, AliyunProperties aliyunProperties, MetricsContext metrics) {
super(client, uri, aliyunProperties, metrics);
}
static OSSOutputFile fromLocation(
OSS client, String location, AliyunProperties aliyunProperties) {
return new OSSOutputFile(
client, new OSSURI(location), aliyunProperties, MetricsContext.nullMetrics());
}
@Override
public PositionOutputStream create() {
if (!exists()) {
return createOrOverwrite();
} else {
throw new AlreadyExistsException("Location already exists: %s", uri());
}
}
@Override
public PositionOutputStream createOrOverwrite() {
return new OSSOutputStream(client(), uri(), aliyunProperties(), metrics());
}
@Override
public InputFile toInputFile() {
return new OSSInputFile(client(), uri(), aliyunProperties(), metrics());
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use createOrOverwrite() if overwrite is intended.
- Choose a unique output location (new metadata path/partition file name) before writing.
- Delete the stale object if it is safe to replace.
- Fix writer concurrency so only one task writes a given path.
Example fix
// before PositionOutputStream out = outputFile.create(); // after PositionOutputStream out = outputFile.createOrOverwrite();
Defensive patterns
Strategy: try-catch
Validate before calling
if (outputFile.exists()) {
// pick a new path or delete intentionally before writing
} Try / catch
try {
out = outputFile.create();
} catch (AlreadyExistsException e) {
// choose a new file location or use createOrOverwrite()
} Prevention
- Use createOrOverwrite() when replacement is intended.
- Generate unique output paths (metadata LocationProvider handles this).
- Avoid retrying writers without cleaning prior partial output.
- Ensure one writer per file path (task affinity, not concurrent retry).
When it happens
Trigger: Calling create() on an OSSOutputFile whose URI points to an object already present in the bucket; using create() instead of createOrOverwrite() to retry a failed write.
Common situations: Retrying a failed commit without cleaning up partial output; two writers racing to write the same file path; re-running a job with the same output location without deleting prior files.
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
- Failed to create RRSA OSS client
- Failed to create file: %s
- Unable to load metrics class: '{}', falling back to null met
- Unclosed input stream created by: {}
- Failed to delete staging file: {}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/79a9150bfb234473.
Report an issue: GitHub.