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

  1. Ensure the emitting SDK produces 16 random bytes for traceId per W3C Trace Context (use the official OpenTelemetry SDK, not hand-rolled IDs).
  2. Drop or fix spans carrying all-zero traceIds before export — they are invalid by spec and should not be sent.
  3. When bridging from 64-bit legacy IDs, zero-pad to 16 bytes and confirm not all zero.
  4. 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

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


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