pinpoint-apm/pinpoint · error · OtlpMappingException

Resource attribute `pinpoint.agentId` is required to save OT

Error message

Resource attribute `pinpoint.agentId` is required to save OTLP metrics to Pinpoint

What it means

parseCommonTags requires the resource attribute `pinpoint.agentId` (in addition to `service.name`) so metrics can be attributed to a specific agent in Pinpoint. When it is missing or empty, OtlpMappingException is thrown. Note the guard has a copy-paste bug: it re-checks `serviceName` instead of `agentId`, so this error only fires when service.name was also empty (or never when only agentId is empty) — a null/empty agentId silently flows into builder.setAgentId.

Source

Thrown at otlpmetric/otlpmetric-collector/src/main/java/com/navercorp/pinpoint/otlp/collector/mapper/OtlpMetricMapper.java:91

    private void map(OtlpMetricData.Builder builder, Metric metric, Map<String, String> commonTags) {
        for (OtlpMetricDataMapper mapper : mappers) {
            mapper.map(builder, metric, commonTags);
        }
    }

    private Map<String, String> parseCommonTags(OtlpMetricData.Builder builder, Map<String, String> tags) {
        Map<String, String> commonTags = new HashMap<>(tags);

        String serviceName = commonTags.remove(OtlpResourceAttributes.KEY_SERVICE_NAME);
        if (StringUtils.isEmpty(serviceName)) {
            throw new OtlpMappingException("Resource attribute `service.name` is required to save OTLP metrics to Pinpoint.");
        }
        builder.setServiceName(serviceName);

        String agentId = commonTags.remove(OtlpResourceAttributes.KEY_PINPOINT_AGENTID);
        if (StringUtils.isEmpty(serviceName)) {
            throw new OtlpMappingException("Resource attribute `pinpoint.agentId` is required to save OTLP metrics to Pinpoint");
        }

        builder.setAgentId(agentId);

        String version = commonTags.remove(OtlpResourceAttributes.KEY_PINPOINT_METRIC_VERSION);
        if (StringUtils.isEmpty(version) == false) {
            builder.setVersion(version);
        }

        return commonTags;
    }
}

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Add the `pinpoint.agentId` resource attribute on the exporter (Resource.builder().put("pinpoint.agentId", agentId)).
  2. Fix the mapper bug so the guard checks the right variable: `if (StringUtils.isEmpty(agentId)) throw ...` (see exampleFix).
  3. If routing through a Collector, use a `resource` processor to inject pinpoint.agentId before export.
  4. Verify the exact attribute key matches OtlpResourceAttributes.KEY_PINPOINT_AGENTID for your Pinpoint version (naming drift across versions).

Example fix

// before (OtlpMetricMapper.java)
String agentId = commonTags.remove(OtlpResourceAttributes.KEY_PINPOINT_AGENTID);
if (StringUtils.isEmpty(serviceName)) {
    throw new OtlpMappingException("Resource attribute `pinpoint.agentId` is required to save OTLP metrics to Pinpoint");
}
// after
String agentId = commonTags.remove(OtlpResourceAttributes.KEY_PINPOINT_AGENTID);
if (StringUtils.isEmpty(agentId)) {
    throw new OtlpMappingException("Resource attribute `pinpoint.agentId` is required to save OTLP metrics to Pinpoint");
}
Defensive patterns

Strategy: validation

Validate before calling

Resource res = Resource.getDefault();
String agentId = res.getAttributes().get(AttributeKey.stringKey("pinpoint.agentId"));
String serviceName = res.getAttributes().get(AttributeKey.stringKey("service.name"));
if (isBlank(serviceName) || isBlank(agentId)) {
    throw new IllegalStateException("Pinpoint OTLP export requires `service.name` and `pinpoint.agentId` resource attributes");
}

Type guard

boolean hasAgentId(io.opentelemetry.api.common.Attributes attrs) {
    String v = attrs.get(AttributeKey.stringKey("pinpoint.agentId"));
    return v != null && !v.isEmpty();
}

Try / catch

try {
    exporter.export(metrics);
} catch (OtlpMappingException e) {
    log.error("Missing Pinpoint resource attribute: {}", e.getMessage());
}

Prevention

When it happens

Trigger: An OTLP metrics payload whose Resource lacks the `pinpoint.agentId` attribute (OtlpResourceAttributes.KEY_PINPOINT_AGENTID) reaches parseCommonTags and service.name is also empty; or the attribute exists but is blank while the faulty serviceName check still evaluates true.

Common situations: 1) Emitting via a stock OpenTelemetry SDK which knows nothing about Pinpoint's custom `pinpoint.agentId` attribute. 2) A Collector `resource` processor that strips non-standard attributes. 3) Version change in the Pinpoint OTLP contract where the attribute key was renamed.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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