pinpoint-apm/pinpoint · error · IllegalStateException

already exist. serviceType:${serviceType}, exist:${exist}

Error message

already exist. serviceType:${serviceType}, exist:${exist}

What it means

The registry builder's addServiceType registers a ServiceType keyed by its integer code. If a ServiceType with that code was already added, the put returns the previous entry and an IllegalStateException is thrown — service type codes must be globally unique. Unlike the name collision (error 333), this guard lives in the builder's add method and fires as soon as the duplicate is added.

Source

Thrown at commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/trace/ServiceTypeRegistry.java:122

        for (Map.Entry<String, List<ServiceType>> entry : table.entrySet()) {
            List<ServiceType> newValue = Collections.unmodifiableList(entry.getValue());
            copy.put(entry.getKey(), newValue);
        }
        return copy;
    }

    static class Builder {

        private final Map<Integer, ServiceType> buildMap = new HashMap<>();

        void addServiceType(ServiceType serviceType) {
            Objects.requireNonNull(serviceType, "serviceType");

            int code = serviceType.getCode();
            final ServiceType exist = this.buildMap.put(code, serviceType);
            if (exist != null) {
                throw new IllegalStateException("already exist. serviceType:" + serviceType + ", exist:" + exist);
            }
        }

        ServiceTypeRegistry build() {
            return new ServiceTypeRegistry(buildMap);
        }
    }


}

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Assign the custom ServiceType an unused code (Pinpoint reserves 0-999 and defines 1000+ ranges; pick from the unallocated range documented for user plugins)
  2. Check the 'exist' part of the message to see which type already holds the code and avoid it
  3. Deduplicate the list of ServiceTypes before adding, e.g. with a check via getServiceType(code) first
  4. Remove duplicate plugin jars from the classpath so types aren't registered twice

Example fix

// before
builder.addServiceType(new DefaultServiceType(1010, "MY_PLUGIN", ...)); // 1010 taken
// after
builder.addServiceType(new DefaultServiceType(9001, "MY_PLUGIN", ...)); // free code
Defensive patterns

Strategy: validation

Validate before calling

if (builder != null && registry.findServiceType(serviceType.getCode()) != null) {
    throw new IllegalStateException("service type code already registered: " + serviceType.getCode());
}
builder.addServiceType(serviceType);

Try / catch

try {
    builder.addServiceType(serviceType);
} catch (IllegalStateException e) {
    LOGGER.error("service type code collision: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling builder.addServiceType() twice with ServiceTypes sharing the same int code, or adding a custom ServiceType whose code equals a built-in one (built-ins occupy fixed ranges, e.g. 1000-1999 server types).

Common situations: Custom plugin picks an arbitrary code that collides with a built-in or another plugin's code; loading two versions of a plugin that both define the same code; copy-pasting a type descriptor and only renaming the string but not the code.

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/7a73e0a0b9ef3550. Report an issue: GitHub.