{"record":{"id":"23f1cbcd17ebda92","repo":"apache/druid","slug":"reference-already-exists","errorCode":null,"errorMessage":"Reference already exists","messagePattern":"Reference already exists","errorType":"exception","errorClass":"RE","httpStatus":null,"severity":"error","filePath":"extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureStorage.java","lineNumber":165,"sourceCode":"   *\n   * @return An OutputStream for writing the blob.\n   */\n  public OutputStream getBlockBlobOutputStream(\n      final String containerName,\n      final String blobName,\n      @Nullable final Long blockSize,\n      @Nullable final Integer maxAttempts\n  ) throws BlobStorageException\n  {\n    final BlockBlobClient blockBlobClient = azureClientFactory\n        .getBlobServiceClient(maxAttempts, defaultStorageAccount)\n        .createBlobContainerIfNotExists(containerName)\n        .getBlobClient(blobName)\n        .getBlockBlobClient();\n\n    // TODO based on the usage here, it might be better to overwrite the existing blob instead; that's what StorageConnector#write documents it does\n    if (blockBlobClient.exists()) {\n      throw new RE(\"Reference already exists\");\n    }\n\n    final BlockBlobOutputStreamOptions options = new BlockBlobOutputStreamOptions();\n    if (blockSize != null) {\n      options.setParallelTransferOptions(new ParallelTransferOptions().setBlockSizeLong(blockSize));\n    }\n\n    return blockBlobClient.getBlobOutputStream(options);\n  }\n\n  /**\n   * Gets the length of the specified block blob.\n   *\n   * @param containerName The name of the storage container.\n   * @param blobName      The name of the blob within the container.\n   *\n   * @return The length of the blob in bytes.\n   */","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/azure-extensions/src/main/java/org/apache/druid/storage/azure/AzureStorage.java#L147-L183","documentation":"AzureStorage.getBlockBlobOutputStream refuses to open an output stream when the target blob already exists, throwing \"Reference already exists\". This enforces no-overwrite semantics for druid storage writes, though the TODO notes StorageConnector#write documents overwrite behavior, so this may change.","triggerScenarios":"Calling getBlockBlobOutputStream (e.g. via StorageConnector.write) for a blobName that already exists in the container — e.g. pushing a segment to an already-used path or writing a report/key twice.","commonSituations":"Re-running an ingestion/push with the same segment id and version; non-unique output paths (missing unique suffix/timestamp); concurrent writers racing on the same key.","solutions":["Use a unique blob name (include partition/timestamp/uuid) for the write","Delete the existing blob first if overwrite is intended","Route writes through an API that documents overwrite semantics, or wait for the noted behavior change","Handle the RE and treat as duplicate-write in caller logic"],"exampleFix":"// before\nconnector.write(\"segments/idx.zip\", data); // fails if exists\n// after\nString key = \"segments/\" + id + \"-\" + System.nanoTime() + \".zip\";\nconnector.write(key, data); // unique reference","handlingStrategy":"try-catch","validationCode":"if (blockBlobClient.exists()) { throw new IllegalStateException(\"blob \" + blobName + \" already exists\"); } // mirror of the library check","typeGuard":null,"tryCatchPattern":"try { connector.write(key, data); } catch (RE e) { if (\"Reference already exists\".equals(e.getMessage())) { /* choose new key or delete existing */ } else throw e; }","preventionTips":["Generate unique blob keys (uuid/timestamp/partition) for every write","Never reuse output paths across retries without deleting first","Serialize concurrent writers to the same key with external coordination","Prefer an overwrite-capable API if rewrites are legitimate"],"tags":["azure","blob-write","duplicate"],"backgroundTag":"file-already-exists","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}