apache/druid · warning

Asked to add data segment that already exists!? server

Error message

Asked to add data segment that already exists!? server[%s], segment[%s]

What it means

DruidServer.addDataSegment increments currSize/totalSegments only when dataSource.addSegmentIfAbsent succeeds; when a segment with the same id already exists it logs this warning and skips. It indicates duplicate segment-add events for the same server.

Solutions

  1. Check why the same segment id was announced twice (historical restart loop, duplicate watchers) in historical and coordinator logs
  2. Ensure each server inventory view instance is registered only once
  3. Ignore if from a one-off reconnect; investigate if currSize/totalSegments deviate from expected values afterward
  4. If in tests, use a fresh DruidServer per test or remove the segment before re-adding
Defensive patterns

Strategy: validation

Validate before calling

// check before re-adding
if (server.getSegment(segment.getId()) != null) { log.info("already present"); return; }

Prevention

When it happens

Trigger: addDataSegment (or addSegment from DruidServer) invoked twice for the same DataSegment id, e.g. replayed inventory events or repeated server segment announcements.

Common situations: Historical re-announcing segments after reconnect, duplicate server inventory view registrations, test suites reusing a DruidServer instance across cases.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/c174d22ab3778dba. Report an issue: GitHub.

Appendix: source

Thrown at server/src/main/java/org/apache/druid/client/DruidServer.java:244

   * replica-reconciliation logic to consult.
   */
  public DruidServer addDataSegment(DataSegment segment, @Nullable PartialLoadProfile profile)
  {
    final long sizeToAdd = (profile != null && profile.loadedBytes() != null)
                           ? profile.loadedBytes()
                           : segment.getSize();
    // ConcurrentHashMap.compute() ensures that all actions for specific dataSource are linearizable.
    dataSources.compute(
        segment.getDataSource(),
        (dataSourceName, dataSource) -> {
          if (dataSource == null) {
            dataSource = new DruidDataSource(dataSourceName, ImmutableMap.of("client", "side"));
          }
          if (dataSource.addSegmentIfAbsent(segment, profile)) {
            currSize.addAndGet(sizeToAdd);
            totalSegments.incrementAndGet();
          } else {
            log.warn(
                "Asked to add data segment that already exists!? server[%s], segment[%s]",
                getName(),
                segment.getId()
            );
          }
          return dataSource;
        }
    );
    return this;
  }

  /**
   * Returns the partial-load profile for the given segment, or {@code null} if the segment was loaded as a regular
   * full-load (no partial-load metadata announced).
   */
  @Nullable
  public PartialLoadProfile getPartialLoadProfile(SegmentId segmentId)
  {

View on GitHub (pinned to 9b90983fd2)