prestodb/presto · error · PrestoException

INVALID_ARGUMENTS

INVALID_ARGUMENTS

Error message

Can not serialize remote transaction handle

What it means

RemoteTransactionHandleCodec.serialize encodes a ConnectorTransactionHandle (cast to RemoteTransactionHandle) into Thrift bytes so transaction context can accompany remote splits. A TProtocolException during encoding is converted to PrestoException INVALID_ARGUMENTS because an unencodable transaction handle is invalid input.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/thrift/RemoteTransactionHandleCodec.java:46

public class RemoteTransactionHandleCodec
        implements ConnectorCodec<ConnectorTransactionHandle>
{
    private final Provider<ThriftCodecManager> thriftCodecManagerProvider;

    public RemoteTransactionHandleCodec(Provider<ThriftCodecManager> thriftCodecManagerProvider)
    {
        this.thriftCodecManagerProvider = requireNonNull(thriftCodecManagerProvider, "thriftCodecManagerProvider is null");
    }

    @Override
    public byte[] serialize(ConnectorTransactionHandle handle)
    {
        try {
            return toThrift((RemoteTransactionHandle) handle, thriftCodecManagerProvider.get().getCodec(RemoteTransactionHandle.class));
        }
        catch (TProtocolException e) {
            throw new PrestoException(INVALID_ARGUMENTS, "Can not serialize remote transaction handle", e);
        }
    }

    @Override
    public ConnectorTransactionHandle deserialize(byte[] bytes)
    {
        try {
            return fromThrift(bytes, thriftCodecManagerProvider.get().getCodec(RemoteTransactionHandle.class));
        }
        catch (TProtocolException e) {
            throw new PrestoException(INVALID_ARGUMENTS, "Can not deserialize remote transaction handle", e);
        }
    }
}

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the cause TProtocolException to find the offending field
  2. Ensure the handle is a RemoteTransactionHandle built through the intended remote-exchange path
  3. Confirm the Thrift codec manager resolves the expected RemoteTransactionHandle codec
  4. Regenerate the transaction handle from the connector instead of reusing a corrupted one

Example fix

// before
return toThrift((RemoteTransactionHandle) handle, thriftCodecManagerProvider.get().getCodec(RemoteTransactionHandle.class));
// after
if (!(handle instanceof RemoteTransactionHandle)) {
    throw new PrestoException(INVALID_ARGUMENTS, "Expected RemoteTransactionHandle, got " + handle.getClass().getSimpleName());
}
return toThrift((RemoteTransactionHandle) handle, thriftCodecManagerProvider.get().getCodec(RemoteTransactionHandle.class));
Defensive patterns

Strategy: validation

Validate before calling

if (!(handle instanceof RemoteTransactionHandle)) {
    throw new PrestoException(INVALID_ARGUMENTS, "serialize expects RemoteTransactionHandle, got " + handle.getClass().getName());
}

Type guard

boolean isEncodableTransactionHandle(ConnectorTransactionHandle handle) {
    return handle instanceof RemoteTransactionHandle;
}

Try / catch

try {
    byte[] bytes = codec.serialize(handle);
} catch (PrestoException e) {
    if (INVALID_ARGUMENTS.equals(e.getErrorCode())) {
        LOG.error(e, "Unserializable transaction handle; regenerating from connector");
        throw new PrestoException(GENERIC_INTERNAL_ERROR, "Transaction handle encode failed", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling serialize() with a handle whose Thrift-registered fields raise TProtocolException during toThrift, or a handle type that fails the RemoteTransactionHandle cast path.

Common situations: Custom connector transaction handles incompatible with the registered Thrift codec; corrupted handle state after coordinator failover; Thrift codec version mismatches.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/c65c5ac4a1ad0452. Report an issue: GitHub.