pinpoint-apm/pinpoint · error · OtlpMappingException

Resource attribute `service.name` is required to save OTLP m

Error message

Resource attribute `service.name` is required to save OTLP metrics to Pinpoint.

What it means

The OTLP metric collector maps incoming OTLP metric data to Pinpoint's metric model. Every metric payload must carry a resource attribute `service.name`, which Pinpoint uses as the application/service identifier. parseCommonTags removes `service.name` from the merged resource+common tag map, and if it is absent or empty it aborts mapping with OtlpMappingException because a metric without a service name cannot be attributed to any Pinpoint application.

Source

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

            logger.info("Failed saving OTLP metric {}: {}", metric.getName(), ex.getMessage());
            return null;
        }

        return builder.build();
    }

    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. Set the `service.name` resource attribute on the OTLP exporter side (OTEL_SERVICE_NAME env var or ServiceResourceDetector in the SDK).
  2. If routing through an OpenTelemetry Collector, keep/insert service.name in a `resource` processor (attributes: service.name: value) before exporting to Pinpoint.
  3. If your agent wraps Pinpoint telemetry, ensure pinpoint.applicationName is mapped to `service.name` in the resource.
  4. Wrap the OTLP submission in a try/catch for OtlpMappingException on the producer side and log/reject the payload with a clear client-side message.

Example fix

// before (client side)
SdkMeterProvider.builder().setResource(Resource.empty())
// after
SdkMeterProvider.builder().setResource(Resource.getDefault().merge(Resource.builder().put("service.name", "my-app").build()))
Defensive patterns

Strategy: validation

Validate before calling

// client-side, before exporting OTLP metrics
Resource res = Resource.getDefault();
String serviceName = res.getAttributes().get(AttributeKey.stringKey("service.name"));
if (serviceName == null || serviceName.isEmpty()) {
    throw new IllegalStateException("OTLP export to Pinpoint requires resource attribute `service.name`");
}

Type guard

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

Try / catch

try {
    otlpGrpcMetricExporter.export(metrics);
} catch (OtlpMappingException | io.opentelemetry.sdk.metrics.internal.export.SdkMeterProviderException e) {
    log.error("Pinpoint rejected OTLP metrics: {}", e.getMessage());
}

Prevention

When it happens

Trigger: An OTLP exporter (e.g. OpenTelemetry SDK, collector pipeline) sends metrics to Pinpoint's OTLP endpoint whose Resource attributes omit `service.name`, or set it to an empty string. Happens with Service.name/OTEL_RESOURCE_ATTRIBUTES not configured on the emitting side, or when a collector's metrics transform stage drops resource attributes.

Common situations: 1) OTEL_SERVICE_NAME / OTEL_RESOURCE_ATTRIBUTES=service.name=... not set on the app emitting metrics. 2) OpenTelemetry Collector `resource` processor deleting the service.name attribute before forwarding to Pinpoint. 3) Custom SDK exporters that build Resource without ServiceResourceDetector.

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