pinpoint-apm/pinpoint · error · IllegalStateException
PTransactionId is not set
Error message
PTransactionId is not set
What it means
GrpcSpanBinder throws IllegalStateException when a received span/spanChunk has no transactionId (PTransactionId unset). Without a transactionId the SpanBo/SpanChunkBo cannot be assembled, since it is the trace identity key, so binding is aborted.
Source
Thrown at commons-server/src/main/java/com/navercorp/pinpoint/common/server/io/GrpcSpanBinder.java:309
SpanChunkBo spanChunkBo = new SpanChunkBo(traceSourceType, owner);
return bind(spanChunkBo, pSpanChunk, requestTime);
}
public SpanChunkBo bind(SpanChunkBo spanChunkBo, PSpanChunk pSpanChunk, long requestTime) {
spanChunkBo.setCollectorAcceptTime(requestTime);
spanChunkBo.setApplicationServiceType((short) pSpanChunk.getApplicationServiceType());
if (pSpanChunk.hasTransactionId()) {
PTransactionId pTransactionId = pSpanChunk.getTransactionId();
ServerTraceId transactionId = newTransactionId(pTransactionId, spanChunkBo.getAgentId());
spanChunkBo.setTransactionId(transactionId);
} else {
if (logger.isWarnEnabled()) {
SpanOwner owner = spanChunkBo.getSpanOwner();
logger.warn("PTransactionId is not set {}/{}/{}", owner.getServiceName(), owner.getApplicationName(), owner.getAgentId());
}
throw new IllegalStateException("PTransactionId is not set");
}
spanChunkBo.setTraceTime(pSpanChunk.getVersion(), pSpanChunk.getKeyTime());
spanChunkBo.setSpanId(pSpanChunk.getSpanId());
spanChunkBo.setEndPoint(pSpanChunk.getEndPoint());
return spanChunkBo;
}
private ServerTraceId newTransactionId(PTransactionId pTransactionId, String spanAgentId) {
final String transactionAgentId = pTransactionId.getAgentId();
if (StringUtils.hasLength(transactionAgentId)) {
return new PinpointServerTraceId(transactionAgentId, pTransactionId.getAgentStartTime(), pTransactionId.getSequence());
} else {
return new PinpointServerTraceId(spanAgentId, pTransactionId.getAgentStartTime(), pTransactionId.getSequence());
}
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Upgrade or fix the agent identified by the logged serviceName/applicationName/agentId to send a valid transactionId
- Check network intermediaries/proxies for payload corruption
- Validate any custom span-producing code sets transactionId before sending
- Drop/reject such spans upstream if agents cannot be fixed
Example fix
// before (hand-crafted protobuf)
PSpanChunk chunk = PSpanChunk.newBuilder().setSpanId(1L).build();
// after
PSpanChunk chunk = PSpanChunk.newBuilder()
.setTransactionId(ByteString.copyFromUtf8("trace-1"))
.setSpanId(1L)
.build(); Defensive patterns
Strategy: validation
Validate before calling
boolean hasTransactionId(PSpanChunk chunk) {
return chunk.hasTransactionId() && !chunk.getTransactionId().isEmpty();
}
// call before binding; skip/reject chunk when false Type guard
boolean isValidSpan(PSpanChunk chunk) {
return chunk != null && chunk.hasTransactionId();
} Try / catch
try {
SpanBo bo = spanBinder.bindSpanChunk(pSpanChunk);
} catch (IllegalStateException e) {
if ("PTransactionId is not set".equals(e.getMessage())) {
// drop span and count metric; fix the emitting agent
}
} Prevention
- Ensure every agent sets transactionId on spans/spanChunks before sending
- Pin agent and collector to compatible versions during upgrades
- Add an ingestion-side validation/counter for spans missing transactionId
- Test custom instrumentation with hand-crafted protobuf against the binder
When it happens
Trigger: Agent sends PSpan or PSpanChunk with transactionId unset/empty, e.g. a buggy or very old agent, or data corrupted in transit/proxying.
Common situations: Mismatched agent/collector versions after upgrade; third-party or custom instrumented agents emitting incomplete spans; test harness sending hand-crafted protobuf messages missing transactionId.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- list size not same
- Failed to request. header={}
- value
- customMetricName must consist of {GroupName}/{MetricName}/La
- unsupported message
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/ddfca176c9a7330f.
Report an issue: GitHub.