Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProtocolError on receive_data after connection is closed #1199

Open
Tronic opened this issue Sep 3, 2019 · 3 comments
Open

ProtocolError on receive_data after connection is closed #1199

Tronic opened this issue Sep 3, 2019 · 3 comments

Comments

@Tronic
Copy link

Tronic commented Sep 3, 2019

I am randomly getting this error on h2 3.1.1 (about once a week on a busy H2 client):

Traceback (most recent call last):
  File "site-packages/h2/connection.py", line 224, in process_input
    func, target_state = self._transitions[(self.state, input_)]
KeyError: (<ConnectionState.CLOSED: 3>, <ConnectionInputs.RECV_PING: 14>)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "nameclient.py", line 84, in recv_task
    for event in self.conn.receive_data(data):
  File "site-packages/h2/connection.py", line 1463, in receive_data
    events.extend(self._receive_frame(frame))
  File "site-packages/h2/connection.py", line 1486, in _receive_frame
    frames, events = self._frame_dispatch_table[frame.__class__](frame)
  File "site-packages/h2/connection.py", line 1725, in _receive_ping_frame
    ConnectionInputs.RECV_PING
  File "site-packages/h2/connection.py", line 229, in process_input
    "Invalid input %s in state %s" % (input_, old_state)
h2.exceptions.ProtocolError: Invalid input ConnectionInputs.RECV_PING in state ConnectionState.CLOSED

Unfortunately the code is somewhat complicated but I believe the connection closing logic to be correct. I never call close_connection and I quit receiving once ConnectionTerminated appears.

Possibly H2 is internally closing the connection due to ping timeout or other issue, and then throws me an error when the peer still sends something. Quite likely this actually happens when my laptop is in sleep, and H2 going ping-timeout meanwhile, with some data still in receive buffers. I would expect a ConnectionTerminated event in that case, after any remaining events are relayed, not an exception.

@ardzoht
Copy link

ardzoht commented Dec 10, 2019

Just want to chime in, we're seeing those errors some times too, we have a gRPC client with HTTP2 proxy, and the client throws this:

 Traceback (most recent call last):
   File "/usr/lib/python3.5/asyncio/events.py", line 127, in _run
     self._callback(*self._args)
   File "/usr/lib/python3.5/asyncio/selector_events.py", line 730, in _read_ready
     self._protocol.data_received(data)
   File "/usr/local/lib/python3.5/dist-packages/aioh2/protocol.py", line 256, in data_received
     events_ = self._conn.receive_data(data)
   File "/usr/local/lib/python3.5/dist-packages/h2/connection.py", line 1463, in receive_data
     events.extend(self._receive_frame(frame))
   File "/usr/local/lib/python3.5/dist-packages/h2/connection.py", line 1486, in _receive_frame
     frames, events = self._frame_dispatch_table[frame.__class__](frame)
   File "/usr/local/lib/python3.5/dist-packages/h2/connection.py", line 1725, in _receive_ping_frame
     ConnectionInputs.RECV_PING
   File "/usr/local/lib/python3.5/dist-packages/h2/connection.py", line 229, in process_input
     "Invalid input %s in state %s" % (input_, old_state)
 h2.exceptions.ProtocolError: Invalid input ConnectionInputs.RECV_PING in state ConnectionState.CLOSED

I'm guessing this is related to the connection being terminated but RECV_PING frames are still being sent?

@zanieb
Copy link

zanieb commented Nov 6, 2022

I believe we are also seeing this in a relatively busy HTTP2 client in PrefectHQ/prefect#7442 — happy to investigate contributing a fix but I'm not sure how this should be handled.

@stephenc-pace
Copy link

I believe this is related to #1181
H2 is closing the connection immeditietly after a GO_AWAY frame is received instead of waiting for a graceful termination after sending the connection terminated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants