{"record":{"id":"3b53eb9bee64697e","repo":"apache/druid","slug":"cannot-simultaneously-replace-and-append-to-existi","errorCode":null,"errorMessage":"Cannot simultaneously replace and append to existing segments. Either dropExisting or appendToExisting should be set to false","messagePattern":"Cannot simultaneously replace and append to existing segments\\. Either dropExisting or appendToExisting should be set to false","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractTask.java","lineNumber":421,"sourceCode":"  protected static IngestionMode computeBatchIngestionMode(@Nullable BatchIOConfig ioConfig)\n  {\n    final boolean isAppendToExisting = ioConfig == null\n        ? BatchIOConfig.DEFAULT_APPEND_EXISTING\n        : ioConfig.isAppendToExisting();\n    final boolean isDropExisting = ioConfig == null ? BatchIOConfig.DEFAULT_DROP_EXISTING : ioConfig.isDropExisting();\n    return computeIngestionMode(isAppendToExisting, isDropExisting);\n  }\n\n  private static IngestionMode computeIngestionMode(boolean isAppendToExisting, boolean isDropExisting)\n  {\n    if (!isAppendToExisting && isDropExisting) {\n      return IngestionMode.REPLACE;\n    } else if (isAppendToExisting && !isDropExisting) {\n      return IngestionMode.APPEND;\n    } else if (!isAppendToExisting) {\n      return IngestionMode.REPLACE_LEGACY;\n    }\n    throw new IAE(\"Cannot simultaneously replace and append to existing segments. \"\n        + \"Either dropExisting or appendToExisting should be set to false\");\n  }\n\n  /**\n   * Emits a metric for this task using the {@link #getMetricBuilder() metric builder}.\n   */\n  public void emitMetric(\n      ServiceEmitter emitter,\n      String metric,\n      Number value\n  )\n  {\n    if (emitter == null || metric == null || value == null) {\n      return;\n    }\n    emitter.emit(getMetricBuilder().setMetric(metric, value));\n  }\n","sourceCodeStart":403,"sourceCodeEnd":439,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/indexing-service/src/main/java/org/apache/druid/indexing/common/task/AbstractTask.java#L403-L439","documentation":"Thrown by AbstractTask.computeIngestionMode when both appendToExisting and dropExisting are true, meaning the task asks to both append to and replace (drop) existing segments at once — a logically contradictory ingestion mode. Druid derives IngestionMode from these two flags and refuses the combination.","triggerScenarios":"Submitting an ingestion or compaction task spec (e.g., ParallelIndexTask, BatchTask, CompactionTask) whose tuningConfig/ioConfig sets dropExisting=true while appendToExisting=true; via native JSON specs or SQL-based compaction configs where both flags were flipped on.","commonSituations":"Copy-pasting a compaction spec with dropExisting=true into an append task without removing appendToExisting; editing task JSON by hand; migration scripts that set both flags to 'true' defensively.","solutions":["Set dropExisting=false to append to existing segments, or set appendToExisting=false to replace them — keep exactly one true.","If replacement is intended (compaction-like behavior), remove appendToExisting from the spec so REPLACE mode is selected.","If appending is intended, remove dropExisting so APPEND mode is selected.","Validate the spec before submission with a JSON-schema or pre-submit check on ioConfig flags."],"exampleFix":"// before\n\"ioConfig\": { \"type\": \"index_parallel\", \"appendToExisting\": true },\n\"tuningConfig\": { \"dropExisting\": true }\n// after (append intended)\n\"ioConfig\": { \"type\": \"index_parallel\", \"appendToExisting\": true },\n\"tuningConfig\": { \"dropExisting\": false }","handlingStrategy":"validation","validationCode":"final boolean append = ioConfig.isAppendToExisting();\nfinal boolean drop = tuningConfig.isDropExisting();\nif (append && drop) throw new IllegalArgumentException(\"Set at most one of appendToExisting/dropExisting to true\");","typeGuard":null,"tryCatchPattern":"try { submitTask(spec); } catch (IAE e) { if (e.getMessage().contains(\"simultaneously replace and append\")) { fix flags and resubmit; } else throw e; }","preventionTips":["Treat dropExisting and appendToExisting as mutually exclusive in spec templates.","Lint compaction/ingestion specs for both flags true before submission.","When migrating specs between task types, reset both flags to defaults."],"tags":["druid","ingestion","config","validation"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}