prestodb/presto · error · RedisProviderSerdeException
Error encoding historicalPlanStatistics value
Error message
Error encoding historicalPlanStatistics value
What it means
HistoricalStatisticsSerde.encodeValue serializes HistoricalPlanStatistics with a Thrift binary protocol writer into a DynamicSliceOutput. If ThriftProtocolUtils.write throws ThriftProtocolException (malformed object, incompatible schema, null required fields), the method wraps it in RedisProviderSerdeException with this message.
Source
Thrown at redis-hbo-provider/src/main/java/com/facebook/presto/statistic/HistoricalStatisticsSerde.java:66
}
@Override
public ByteBuffer encodeKey(String key)
{
return ByteBuffer.wrap(key.getBytes(StandardCharsets.UTF_8));
}
@Override
public ByteBuffer encodeValue(HistoricalPlanStatistics historicalPlanStatistics)
{
ThriftCodec<HistoricalPlanStatistics> writeCodec = thriftCodecManager.getCodec(HistoricalPlanStatistics.class);
SliceOutput dynamicSliceOutput = new DynamicSliceOutput(ESTIMATED_BUFFER_SIZE_BYTES);
try {
ThriftProtocolUtils.write(historicalPlanStatistics, writeCodec, Protocol.BINARY, dynamicSliceOutput);
return ByteBuffer.wrap(dynamicSliceOutput.slice().getBytes());
}
catch (ThriftProtocolException e) {
throw new RedisProviderSerdeException("Error encoding historicalPlanStatistics value", e);
}
}
@Override
public HistoricalPlanStatistics decodeValue(ByteBuffer byteBuffer)
{
ThriftCodec<HistoricalPlanStatistics> readCodec = thriftCodecManager.getCodec(HistoricalPlanStatistics.class);
try {
return ThriftProtocolUtils.read(readCodec, Protocol.BINARY, Slices.wrappedBuffer(byteBuffer).getInput());
}
catch (ThriftProtocolException e) {
throw new RedisProviderSerdeException("Error decoding historicalPlanStatistics value", e);
}
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- Check the ThriftProtocolException cause for the specific field/schema mismatch and align the HistoricalPlanStatistics schema with the writeCodec
- Regenerate/update Thrift codec classes after a schema version change
- Validate the HistoricalPlanStatistics object (required fields present) before encoding
- Catch and log at the call site (encodedValue) to avoid losing the whole statistics pipeline
Example fix
// before
HistoricalPlanStatistics stats = new HistoricalPlanStatistics(); // required fields unset
serde.encodeValue(stats);
// after
if (stats == null || stats.getPlans() == null) {
throw new IllegalArgumentException("HistoricalPlanStatistics missing required fields");
}
serde.encodeValue(stats); Defensive patterns
Strategy: try-catch
Validate before calling
if (stats == null) throw new IllegalArgumentException("historicalPlanStatistics must not be null"); Try / catch
try {
ByteBuffer encoded = serde.encodeValue(stats);
} catch (RedisProviderSerdeException e) {
log.error("Failed to encode HBO stats", e.getCause());
// skip caching this entry rather than failing the query
} Prevention
- Validate required HistoricalPlanStatistics fields before encoding
- Keep Thrift schema and codec versions in sync across Presto upgrades
- Log the underlying ThriftProtocolException to identify the offending field
When it happens
Trigger: Calling encodeValue with a HistoricalPlanStatistics whose schema is incompatible with the configured writeCodec (schema evolution mismatch), or with fields the Thrift writer cannot serialize.
Common situations: HBO statistics schema changed between Presto versions so old objects no longer match the write codec; a partially constructed HistoricalPlanStatistics (missing required fields) is passed in; Thrift codec misconfiguration.
Related errors
- Error decoding key planHash which was of type String
- INVALID_ARGUMENTS
- INVALID_ARGUMENTS
- Invalid NodeState value:
- INVALID_ARGUMENTS
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/5d2235436df5af12.
Report an issue: GitHub.