pinpoint-apm/pinpoint · warning

Failed to create metricId. metric:{}

Error message

Failed to create metricId. metric:{}

What it means

After passing the filter, register(IntCounter) calls customMetricIdGenerator.create(name); if the generator returns NOT_REGISTERED (invalid name or the ID limit exhausted), the service logs "Failed to create metricId" and returns false. This means the metric name was either invalid (see CustomMetricIdGenerator validation) or the profiler already registered the maximum number of custom metric IDs (limitIdNumber).

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/monitor/metric/DefaultCustomMetricRegistryService.java:67

    public DefaultCustomMetricRegistryService(int limitIdNumber, CustomMetricRegistryFilter filter) {
        this.customMetricIdGenerator = new CustomMetricIdGenerator(limitIdNumber);
        this.filter = Objects.requireNonNull(filter, "filter");
    }

    @Override
    public boolean register(IntCounter intCounter) {
        Objects.requireNonNull(intCounter, "intCount");

        boolean filter = this.filter.filter(intCounter);
        if (filter) {
            LOGGER.warn("Failed to register CustomMetric({}). message:not allowed metric", intCounter);
            return false;
        }

        int id = customMetricIdGenerator.create(intCounter.getName());
        if (id == CustomMetricIdGenerator.NOT_REGISTERED) {
            LOGGER.warn("Failed to create metricId. metric:{}", intCounter);
            return false;
        }

        IntCounterWrapper customMetricWrapper = customMetricWrapperFactory.create(id, intCounter);
        return add(customMetricWrapper);
    }

    @Override
    public boolean register(LongCounter longCounter) {
        Objects.requireNonNull(longCounter, "longCount");

        boolean filter = this.filter.filter(longCounter);
        if (filter) {
            LOGGER.warn("Failed to register CustomMetric({}). message:not allowed metric", longCounter);
            return false;
        }

        int id = customMetricIdGenerator.create(longCounter.getName());

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Reduce the number of distinct custom metrics; aggregate dynamic values into a bounded label set.
  2. Raise the custom metric ID limit in profiler configuration and restart the agent.
  3. Sanitize metric names to satisfy CustomMetricIdGenerator validation.
  4. Handle register() returning false gracefully so metric failures never affect business logic.

Example fix

// before: unbounded dynamic names exhaust IDs
registryService.register(new IntCounterCounterAdapter("uri." + requestUri));
// after: bound cardinality
registryService.register(new IntCounterCounterAdapter("uri." + normalizePattern(requestUri)));
Defensive patterns

Strategy: validation

Validate before calling

// Bound cardinality before registering
assert distinctMetricNames.size() <= MAX_CUSTOM_METRICS : "too many custom metrics";

Type guard

boolean registerable(IntCounter c) { return c.getName() != null && c.getName().matches("[A-Za-z0-9_]+"); }

Try / catch

if (!registryService.register(counter)) {
    logger.warn("metric {} not registered (invalid name or ID limit reached)", counter.getName());
}

Prevention

When it happens

Trigger: Registering an IntCounter with an invalid name (bad characters/length), or registering more distinct custom metrics than the configured limit (currentId >= limitIdNumber).

Common situations: Dynamically generating metric names per URL/user so the ID pool runs out; apps registering many metrics at startup; invalid names coming from unsanitized dynamic strings.

Related errors


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