pinpoint-apm/pinpoint · error · IllegalArgumentException
agentIndex not found:${transactionId}
Error message
agentIndex not found:${transactionId} What it means
TransactionIdUtils.parseTransactionId parses the Pinpoint transactionId string format agentId^agentStartTime^transactionSequence (delimiter-separated). If nextIndex finds no delimiter at position 0, the string has no separator and cannot contain an agentId, so an IllegalArgumentException with 'agentIndex not found:<id>' is thrown.
Source
Thrown at commons-profiler/src/main/java/com/navercorp/pinpoint/common/profiler/util/TransactionIdUtils.java:89
final byte[] buffer = new byte[bufferSize];
buffer[0] = VERSION;
int offset = VERSION_SIZE;
// write prefix String
offset = BytesUtils.writeVar32(zigZagAgentIdLength, buffer, offset);
if (agentIdBytes != null) {
offset = BytesUtils.writeBytes(buffer, offset, agentIdBytes);
}
offset = BytesUtils.writeVar64(agentStartTime, buffer, offset);
BytesUtils.writeVar64(transactionSequence, buffer, offset);
return buffer;
}
public static TransactionId parseTransactionId(final String transactionId) {
Objects.requireNonNull(transactionId, "transactionId");
final int agentIdIndex = nextIndex(transactionId, 0);
if (agentIdIndex == -1) {
throw new IllegalArgumentException("agentIndex not found:" + transactionId);
}
if (!IdValidateUtils.checkId(transactionId, 0, agentIdIndex)) {
throw new IllegalArgumentException("invalid transactionId:" + transactionId);
}
final String agentId = transactionId.substring(0, agentIdIndex);
final int agentStartTimeIndex = nextIndex(transactionId, agentIdIndex + 1);
if (agentStartTimeIndex == -1) {
throw new IllegalArgumentException("agentStartTimeIndex not found:" + transactionId);
}
final long agentStartTime = parseLong(transactionId, agentIdIndex + 1, agentStartTimeIndex);
int transactionSequenceIndex = nextIndex(transactionId, agentStartTimeIndex + 1);
if (transactionSequenceIndex == -1) {
// next index may not exist since default value does not have a delimiter after transactionSequence.
// may need fixing when id spec changes
transactionSequenceIndex = transactionId.length();
}View on GitHub (pinned to 744c3d3075)
Solutions
- Print/inspect the offending string and confirm it uses the expected delimiter-separated format (agentId^agentStartTime^transactionSequence).
- URL-decode or un-escape the transactionId before parsing if it came from a web request or query string.
- Only pass strings produced by TransactionIdUtils.formatTransactionId; validate the input (contains the delimiter, correct number of segments) before calling parseTransactionId.
Example fix
// before
TransactionId id = TransactionIdUtils.parseTransactionId(requestParam);
// after
if (transactionId.contains(TransactionIdUtils.TRANSACTION_ID_DELIMITER)) {
TransactionId id = TransactionIdUtils.parseTransactionId(requestParam);
} else {
throw new IllegalArgumentException("Not a formatted pinpoint transactionId: " + requestParam);
} Defensive patterns
Strategy: validation
Validate before calling
boolean isParseable(String id) {
return id != null && !id.isEmpty()
&& id.indexOf(TransactionIdUtils.TRANSACTION_ID_DELIMITER) > 0;
}
// call only if isParseable(rawId) Try / catch
try {
TransactionId id = TransactionIdUtils.parseTransactionId(rawId);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().startsWith("agentIndex not found")) {
logger.warn("Malformed transactionId (missing delimiter): {}", rawId);
} else { throw e; }
} Prevention
- Only pass strings produced by TransactionIdUtils.formatTransactionId.
- URL-decode ids taken from query strings or HTML links before parsing.
- Reject unformatted ids (UUIDs, timestamps) at the API boundary.
- Log the raw string on failure to spot encoding/truncation issues early.
When it happens
Trigger: Passing a transactionId string that contains no delimiter (the first nextIndex() over the default separator returns -1), e.g. calling TransactionIdUtils.parseTransactionId("abcdef1234") or passing a UUID/timestamp instead of a Pinpoint-encoded transactionId.
Common situations: Parsing user-supplied or truncated transaction ids from logs/UI links that were URL-encoded or mangled (e.g. the '^' delimiter lost by shell, HTML or CSV processing); passing an internal numeric id where the formatted string was expected; version mismatch where an older/newer transactionId format is fed to this parser.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- invalid transactionId:${transactionId}
- invalid signature :
- invalid signature. objectName not found :
- '(' not found. signature:
- ')' not found. signature:
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/8673f5546e30c82b.
Report an issue: GitHub.