pinpoint-apm/pinpoint · error · IllegalArgumentException
invalid traceId: ${error}
Error message
invalid traceId: ${error} What it means
OtlpIdValidator.validateTraceId checks an incoming OTLP traceId ByteString for emptiness, correct 16-byte length, and non-all-zero content (the W3C/OTLP invalid-trace-id rule). Any violation throws IllegalArgumentException with the specific reason. Valid trace IDs are required to key spans into pinpoint's trace storage.
Source
Thrown at otlptrace/otlptrace-collector/src/main/java/com/navercorp/pinpoint/otlp/trace/collector/mapper/OtlpIdValidator.java:71
return spanIdError(spanId) == null;
}
/**
* A parent span reference is valid when it is either absent (a root span) or itself a valid span ID.
* A present-but-malformed parent is treated as invalid so the owning span can be rejected.
*/
public static boolean isValidParentSpanId(ByteString parentSpanId) {
return ByteStringUtils.isEmpty(parentSpanId) || isValidSpanId(parentSpanId);
}
/**
* @return the 16-byte trace ID
* @throws IllegalArgumentException if empty, not 16 bytes, or all-zero
*/
public static byte[] validateTraceId(ByteString traceId) {
final String error = traceIdError(traceId);
if (error != null) {
throw new IllegalArgumentException("invalid traceId: " + error);
}
return traceId.toByteArray();
}
/**
* @return the span ID as a big-endian long
* @throws IllegalArgumentException if empty, not 8 bytes, or all-zero
*/
public static long validateSpanId(ByteString spanId) {
final String error = spanIdError(spanId);
if (error != null) {
throw new IllegalArgumentException("invalid spanId: " + error);
}
return ByteStringUtils.parseLong(spanId);
}
private static String traceIdError(ByteString traceId) {
return idError(traceId, TRACE_ID_LEN);View on GitHub (pinned to 744c3d3075)
Solutions
- Ensure the emitting SDK produces 16 random bytes for traceId per W3C Trace Context (use the official OpenTelemetry SDK, not hand-rolled IDs).
- Drop or fix spans carrying all-zero traceIds before export — they are invalid by spec and should not be sent.
- When bridging from 64-bit legacy IDs, zero-pad to 16 bytes and confirm not all zero.
- Wrap parse/export code in try-catch for IllegalArgumentException and log-and-drop the offending span instead of failing the whole batch.
Example fix
// before byte[] traceId = new byte[8]; // wrong length // after byte[] traceId = new byte[16]; ThreadLocalRandom.current().nextBytes(traceId); // 16 random bytes, not all zero
Defensive patterns
Strategy: validation
Validate before calling
boolean validTraceId(byte[] id) {
return id != null && id.length == 16 && !Arrays.equals(id, new byte[16]);
} Type guard
static boolean isUsableTraceId(ByteString traceId) {
return traceId != null
&& traceId.size() == 16
&& !traceId.equals(ByteString.copyFrom(new byte[16]));
} Try / catch
try {
byte[] traceId = OtlpIdValidator.validateTraceId(span.getTraceId());
} catch (IllegalArgumentException e) {
log.warn("dropping span: {}", e.getMessage());
return; // skip invalid span, keep processing the batch
} Prevention
- Use the official OpenTelemetry SDK to generate 16-byte trace IDs
- Never export spans with all-zero or empty trace IDs
- Zero-pad legacy 64-bit IDs to 16 bytes when bridging formats
- Add batch pre-validation that drops invalid IDs before export
When it happens
Trigger: Exporting spans whose parent SDK generated a traceId that is empty, not exactly 16 bytes, or all zero bytes (0x00 * 16, the OTLP 'invalid id' sentinel) — e.g. spans created outside a sampled context.
Common situations: Custom/naive tracers generating 8-byte or 32-byte trace IDs; manually constructed spans in tests or bridges using empty ByteString as a placeholder; converting from another tracing format (e.g. 64-bit legacy IDs) without padding to 16 bytes.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Resource attribute `service.name` is required to save OTLP m
- Resource attribute `pinpoint.agentId` is required to save OT
- invalid spanId: ${error}
- invalid pinpoint.agentName=${agentName}
- annotationKey name must not be empty
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/01310251f5301946.
Report an issue: GitHub.