{"record":{"id":"6306fc937766d91e","repo":"apache/iceberg","slug":"location-already-exists-s-6306fc","errorCode":null,"errorMessage":"Location already exists: %s","messagePattern":"Location already exists: (.+?)","errorType":"exception","errorClass":"AlreadyExistsException","httpStatus":null,"severity":"error","filePath":"aws/src/main/java/org/apache/iceberg/aws/s3/S3OutputFile.java","lineNumber":66,"sourceCode":"      S3AsyncClient asyncClient,\n      S3URI uri,\n      S3FileIOProperties s3FileIOProperties,\n      MetricsContext metrics) {\n    super(client, asyncClient, uri, s3FileIOProperties, metrics);\n  }\n\n  /**\n   * Create an output stream for the specified location if the target object does not exist in S3 at\n   * the time of invocation.\n   *\n   * @return output stream\n   */\n  @Override\n  public PositionOutputStream create() {\n    if (!exists()) {\n      return createOrOverwrite();\n    } else {\n      throw new AlreadyExistsException(\"Location already exists: %s\", uri());\n    }\n  }\n\n  @Override\n  public PositionOutputStream createOrOverwrite() {\n    try {\n      return new S3OutputStream(client(), uri(), s3FileIOProperties(), metrics());\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to create output stream for location: \" + uri(), e);\n    }\n  }\n\n  @Override\n  public InputFile toInputFile() {\n    return new S3InputFile(client(), asyncClient(), uri(), null, s3FileIOProperties(), metrics());\n  }\n\n  @Override","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/aws/src/main/java/org/apache/iceberg/aws/s3/S3OutputFile.java#L48-L84","documentation":"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.","triggerScenarios":"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).","commonSituations":"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().","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."],"exampleFix":"// before\nOutputFile out = io.newOutputFile(\"s3://bucket/data/file.parquet\");\nPositionOutputStream s = out.create(); // AlreadyExistsException\n// after\nOutputFile out = io.newOutputFile(\"s3://bucket/data/file-\" + UUID.randomUUID() + \".parquet\");\nPositionOutputStream s = out.createOrOverwrite();","handlingStrategy":"try-catch","validationCode":"// Java\nOutputFile out = io.newOutputFile(path);\nif (out.exists()) {\n  path = path + \"-\" + UUID.randomUUID();\n  out = io.newOutputFile(path);\n}","typeGuard":null,"tryCatchPattern":"// Java\ntry {\n  os = outFile.create();\n} catch (AlreadyExistsException e) {\n  os = outFile.createOrOverwrite(); // or regenerate a unique path\n}","preventionTips":["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"],"tags":["s3","io","conflict","fileio"],"backgroundTag":"file-already-exists","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}