prestodb/presto · error · IllegalStateException
e.getMessage()
Error message
e.getMessage()
What it means
parseTransactionId wraps any exception from TransactionId.valueOf into an IllegalStateException carrying only e.getMessage(). It means the X-Presto-Transaction-Id header value is not a valid encoded transaction id, so the router cannot reconstruct the transaction for session routing.
Source
Thrown at presto-plan-checker-router-plugin/src/main/java/com/facebook/presto/router/scheduler/HttpRequestSessionContext.java:411
throw new IllegalStateException(format("Invalid %s header: %s", PRESTO_PREPARED_STATEMENT, e.getMessage()));
}
preparedStatements.put(statementName, sqlString);
}
return preparedStatements.build();
}
private static Optional<TransactionId> parseTransactionId(String transactionId)
{
transactionId = trimEmptyToNull(transactionId);
if (transactionId == null || transactionId.equalsIgnoreCase("none")) {
return Optional.empty();
}
try {
return Optional.of(TransactionId.valueOf(transactionId));
}
catch (Exception e) {
throw new IllegalStateException(e.getMessage());
}
}
private static Map<SqlFunctionId, SqlInvokedFunction> parseSessionFunctionHeader(Map<String, List<String>> headerMap)
{
ImmutableMap.Builder<SqlFunctionId, SqlInvokedFunction> sessionFunctions = ImmutableMap.builder();
for (String header : splitSessionHeader(headerMap.getOrDefault(PRESTO_SESSION_FUNCTION, emptyList()))) {
List<String> nameValue = Splitter.on('=').limit(2).trimResults().splitToList(header);
assertRequest(nameValue.size() == 2, "Invalid %s header", PRESTO_SESSION_FUNCTION);
String serializedFunctionSignature;
String serializedFunctionDefinition;
try {
serializedFunctionSignature = urlDecode(nameValue.get(0));
serializedFunctionDefinition = urlDecode(nameValue.get(1));
}
catch (IllegalArgumentException e) {
throw new IllegalArgumentException(format("Invalid %s header: %s", PRESTO_SESSION_FUNCTION, e.getMessage()));View on GitHub (pinned to 55bb57d202)
Solutions
- Remove the X-Presto-Transaction-Id header so the router starts a fresh (autocommit) session
- Reuse the transaction id exactly as issued by the coordinator's response headers, unmodified
- Verify the id was not truncated/mangled by an intermediary; resend the request unmodified from the original client
Example fix
// before curl -H "X-Presto-Transaction-Id: 'some id'" ... // after curl -H "X-Presto-Transaction-Id: 5f0a...full-issued-id..." ...
Defensive patterns
Strategy: validation
Validate before calling
boolean looksLikeTransactionId(String v) {
return v != null && !v.isBlank() && v.trim().equals(v) && !v.contains(" ");
} Try / catch
try { routerCall(request); }
catch (IllegalStateException e) { log.warn("Dropping bad transaction id: {}", e.getMessage()); request.removeHeader("X-Presto-Transaction-Id"); retryWithoutTransaction(); } Prevention
- Echo transaction ids back exactly as issued, unmodified
- Omit the header entirely for autocommit queries
- Never hand-edit or wrap ids in quotes when testing with curl
When it happens
Trigger: A request carries X-Presto-Transaction-Id with a corrupted, truncated, or hand-crafted value that TransactionId.valueOf cannot decode (bad base64/UUID structure).
Common situations: Copy-pasting a transaction id with whitespace or quotes into a curl test, stale ids from a restarted cluster, proxies mangling long header values.
Related errors
- Unsupported resource name %s
- Unsupported format for resource estimate '%s': %s
- format(format, args)
- Invalid %s header: %s
- Invalid %s header
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5507c7314409b7d2.
Report an issue: GitHub.