Netty client has two thread pools. Event loop thread pool which is responsible for handling socket events and another is a worker thread pool which is used to delegate busy work from event loop threads so that they can continue handling socket events. When programming in Netty, ideally, the event loop should never be blocked and must be kept free to respond to events.
In case of exceptional completion of readComplete which could be triggered by a server sending an error code in the response, the event loop thread is used to perform the clean up logic which could involve an expensive replaceConnection. This blocks the event loop.