pinpoint-apm/pinpoint · warning

duplicated span found

Error message

duplicated span found:{}

What it means

FilteredMapBuilder builds a transaction span map keyed by spanId while constructing a filtered application map. When two SpanBo objects share the same spanId, the second overwrites or is flagged as a duplicate via this warning. Pinpoint expects spanIds to be unique within a transaction; duplicates indicate corrupted or duplicated trace data from HBase.

Solutions

  1. Check why the agent emitted duplicate spanIds (agent version bugs, ID generator issues) and upgrade the agent
  2. Scan/deduplicate the span rows in HBase for the affected transactionId
  3. Verify HBase write path (replication, retry configuration) is not duplicating rows
  4. If duplicates are expected and harmless, confirm the map-add overwrites deterministically; otherwise treat the second span as corrupted data

Example fix

// before
if (transactionSpanMap.containsKey(span.getSpanId())) {
    logger.warn("duplicated span found:{}", span);
}
transactionSpanMap.add(span.getSpanId(), span);
// after
SpanBo previous = transactionSpanMap.putIfAbsent(span.getSpanId(), span);
if (previous != null) {
    logger.warn("duplicated span found:{} (keeping first)", span);
}
Defensive patterns

Strategy: validation

Validate before calling

// before building the map, detect duplicate spanIds
Set<Long> seen = new HashSet<>();
for (SpanBo span : spans) {
    if (!seen.add(span.getSpanId())) {
        logger.warn("duplicate spanId {} in transaction {}", span.getSpanId(), span.getTransactionId());
    }
}

Prevention

When it happens

Trigger: A filtered trace query returns multiple SpanBo rows with the same spanId (e.g. duplicate span rows written to HBase, span retry/re-serialization, or a span whose spanId collides due to generator misconfiguration).

Common situations: HBase replication glitches or region-server retries writing the same span twice; agent-side spanId duplication after clock/ID-generator misconfiguration; replaying/importing trace dumps into HBase.

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 pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/d39fd5aafe22ccde. Report an issue: GitHub.

Appendix: source

Thrown at web/src/main/java/com/navercorp/pinpoint/web/applicationmap/map/FilteredMapBuilder.java:312

        final Dot dot = this.dotExtractor.newDot(span);
        this.dotExtractor.addDot(srcApplication, dot);
    }

    private MultiValueMap<Long, SpanBo> createTransactionSpanMap(List<SpanBo> transaction) {
        final MultiValueMap<Long, SpanBo> transactionSpanMap = new LinkedMultiValueMap<>(transaction.size());
        for (SpanBo span : transaction) {
            if (span.getTraceSourceType() == TraceSourceType.OPENTELEMETRY) {
                if (isParentSpanId(span.getSpanId(), transaction)) {
                    transactionSpanMap.add(span.getSpanId(), span);
                }

                createOpenTelemetryTransactionSpanMap(transaction, transactionSpanMap, span, span.getSpanEventBoList());
                for (SpanChunkBo spanChunkBo : span.getSpanChunkBoList()) {
                    createOpenTelemetryTransactionSpanMap(transaction, transactionSpanMap, span, spanChunkBo.getSpanEventBoList());
                }
            } else {
                if (transactionSpanMap.containsKey(span.getSpanId())) {
                    logger.warn("duplicated span found:{}", span);
                }
                transactionSpanMap.add(span.getSpanId(), span);
            }
        }
        return transactionSpanMap;
    }

    private void createOpenTelemetryTransactionSpanMap(List<SpanBo> transaction, MultiValueMap<Long, SpanBo> transactionSpanMap, SpanBo span, List<SpanEventBo> spanEventBoList) {
        for (SpanEventBo spanEventBo : spanEventBoList) {
            long spanId = OpenTelemetryAnnotationValueUtils.getSpanId(spanEventBo.getAnnotationBoList());
            if (spanId != OpenTelemetryAnnotationValueUtils.DEFAULT_SPAN_ID) {
                if (isParentSpanId(spanId, transaction)) {
                    transactionSpanMap.add(spanId, span);
                }
            }
        }
    }

View on GitHub (pinned to 744c3d3075)