pinpoint-apm/pinpoint · error

Duplicated cluster key detected: key =

Error message

Duplicated cluster key detected: key = {}, num = {}

What it means

Warn log in GrpcAgentConnectionRepository.getConnection: multiple live connections share the same ClusterKey (agentId + startTimestamp + socket), meaning a duplicate agent connection was registered; the code still proceeds but picks among ambiguous candidates.

Solutions

  1. Investigate why the agent opened parallel collector connections (e.g. collector restart, half-open sockets)
  2. Ensure stale connections are evicted on disconnect or lease expiry
  3. Prefer the newest connection deterministically when duplicates remain
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/receiver/grpc/GrpcAgentConnectionRepository.java:60 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/4e7d80147b0278d0. Report an issue: GitHub.

Appendix: source

Thrown at realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/receiver/grpc/GrpcAgentConnectionRepository.java:60

    public void remove(GrpcAgentConnection conn) {
        this.connMap.remove(conn.getClusterKey(), conn);
    }

    Collection<GrpcAgentConnection> getConnections() {
        return new ArrayList<>(this.connMap.values());
    }

    public GrpcAgentConnection getConnection(ClusterKey key) {
        Collection<GrpcAgentConnection> candidates = this.connMap.get(key);

        final int size = candidates.size();
        if (size == 0) {
            return null;
        }
        if (size > 1) {
            if (logger.isWarnEnabled()) {
                logger.warn("Duplicated cluster key detected: key = {}, num = {}", key, size);
            }
        }

        synchronized (this.connMap) {
            final Iterator<GrpcAgentConnection> iterator = candidates.iterator();
            if (iterator.hasNext()) {
                return iterator.next();
            } else {
                return null;
            }
        }
    }

    @Override
    public Collection<ClusterPoint> getClusterPointList() {
        Collection<GrpcAgentConnection> values = this.connMap.values();
        return new ArrayList<>(values);
    }

View on GitHub (pinned to 744c3d3075)