You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@thrift.apache.org by "Dmytro Shteflyuk (Jira)" <ji...@apache.org> on 2026/07/24 14:58:00 UTC

[jira] [Created] (THRIFT-6121) Ruby HeaderProtocol emits unparseable errors for unknown protocol IDs

Dmytro Shteflyuk created THRIFT-6121:
----------------------------------------

             Summary: Ruby HeaderProtocol emits unparseable errors for unknown protocol IDs
                 Key: THRIFT-6121
                 URL: https://issues.apache.org/jira/browse/THRIFT-6121
             Project: Thrift
          Issue Type: Bug
          Components: Ruby - Library
            Reporter: Dmytro Shteflyuk
            Assignee: Dmytro Shteflyuk


h3. Problem

When Ruby HeaderProtocol reads an otherwise valid Header frame containing an unknown subprotocol ID, it raises a ProtocolException and attempts to return an INVALID_PROTOCOL ApplicationException. The response Header frame still advertises the unknown, peer-supplied subprotocol ID, however, so the receiver cannot select a Binary or Compact decoder to read the error. The response also replaces the incoming Header sequence ID with zero.

h3. Client impact

A client cannot decode the typed application error and instead fails again while selecting a protocol for the response. Replacing the sequence ID also prevents the response from being correlated with the request that caused it. The useful "Unknown protocol ID" diagnostic is therefore trapped inside a response that a normal HeaderProtocol reader cannot consume.

h3. Reproduction

Save the following as {{/tmp/header_unknown_protocol.rb}}:

{code:language=ruby}
require "thrift"

# Header frame with sequence ID 77 and unknown subprotocol ID 16.
frame = [14, 0x0fff, 0, 77, 1].pack("NnnNn")
frame << "\x10\x00\x00\x00".b

buffer = Thrift::MemoryBufferTransport.new(frame)
protocol = Thrift::HeaderProtocol.new(buffer)

begin
  protocol.read_message_begin
rescue Thrift::ProtocolException
end

response = buffer.read(buffer.available)
puts "response_protocol_id=#{response.getbyte(14)} " \
     "response_sequence_id=#{response.byteslice(8, 4).unpack1("N")} " \
     "bytes=#{response.bytesize}"

reader = Thrift::HeaderProtocol.new(
  Thrift::MemoryBufferTransport.new(response)
)
reader.read_message_begin
{code}

Run it from {{lib/rb}}:

{code:bash}
bundle exec ruby -Ilib /tmp/header_unknown_protocol.rb
{code}

The response retains protocol ID 16, loses sequence ID 77, and cannot be parsed:

{code}
response_protocol_id=16 response_sequence_id=0 bytes=50
Thrift::ProtocolException: Unknown protocol ID: 16
{code}

h3. Expected behavior

The error response should use the HeaderProtocol instance's configured, supported default subprotocol and preserve the parsed Header sequence ID. A fresh HeaderProtocol reader should be able to decode an EXCEPTION message containing an INVALID_PROTOCOL ApplicationException with the original diagnostic. If a malformed header cannot be parsed far enough to obtain safe response metadata, handling it must not recursively emit another unparseable response.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)