pinpoint-apm/pinpoint · warning

Invalid from UserNode:{}

Error message

Invalid from UserNode:{}

What it means

The 'Invalid from UserNode' case in SimplifiedNodeHistogramFactory.createUserNodeHistogram: more than one incoming link exists for the User node. The factory logs the full link list and falls back to using the first link (index 0) as the histogram source, so the simplified histogram is built from an arbitrary duplicate link.

Source

Thrown at web/src/main/java/com/navercorp/pinpoint/web/applicationmap/appender/histogram/SimplifiedNodeHistogramFactory.java:88

                    find = new Histogram(histogram.getServiceType());
                    agentHistogramMap.put(histogram.getId(), find);
                }
                find.add(histogram.getHistogram());
            }
        }
        return agentHistogramMap;
    }

    @Override
    public NodeHistogram createUserNodeHistogram(Application userApplication, Range range, LinkList linkList) {
        // for User nodes, find its source link and create the histogram
        final List<Link> fromLink = linkList.findFromLink(userApplication);
        if (fromLink.isEmpty()) {
            logger.warn("from UserNode not found:{}", userApplication);
            return createEmptyNodeHistogram(userApplication, range);
        } else if (fromLink.size() > 1) {
            // log and use first(0) link.
            logger.warn("Invalid from UserNode:{}", linkList.getLinkList());
        }
        final Link sourceLink = fromLink.get(0);

        NodeHistogram.Builder builder = NodeHistogram.newBuilder(userApplication, range);
        builder.setApplicationHistogram(sourceLink.getHistogram());
        return builder.build();
    }

    @Override
    public NodeHistogram createQueueNodeHistogram(Application queueApplication, Range range, LinkList linkList) {
        final List<Link> toLinkList = linkList.findToLink(queueApplication);
        if (toLinkList.isEmpty()) {
            return NodeHistogram.empty(queueApplication, range);
        }

        // create applicationHistogram
        final Histogram applicationHistogram = new Histogram(queueApplication.getServiceType());
        for (Link link : toLinkList) {

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Deduplicate user links before invoking the factory (merge histograms or keep a single canonical USER->APP link).
  2. Review the link append/merge logic that allows more than one link with the same from/to user application.
  3. Constrain the requested range so overlapping link snapshots are not combined.
  4. If the first-link choice is acceptable, downgrade the issue but record which link was selected for traceability.

Example fix

// before
final Link sourceLink = fromLink.get(0);
// after
final Link sourceLink = fromLink.stream()
        .distinct()
        .findFirst()
        .orElseThrow(() -> new IllegalStateException("missing user link: " + userApplication));
Defensive patterns

Strategy: validation

Validate before calling

List<Link> fromLinks = linkList.findFromLink(userApplication);
if (fromLinks.size() > 1) {
    logger.warn("simplified map: {} duplicate user links for {}", fromLinks.size(), userApplication);
}

Prevention

When it happens

Trigger: Calling SimplifiedNodeHistogramFactory.createUserNodeHistogram(userApplication, range, linkList) when findFromLink(userApplication).size() > 1 — duplicated USER->APP links present in the LinkList for the same user application and range.

Common situations: Simplified map mode after merging map data from multiple sources that each emitted a user link; duplicated user links from repeated link-append runs; LinkList assembled from overlapping time ranges producing two user links.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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