From 79fee038fb832813db303903347f3cedd3abffc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnaud=20Cogolu=C3=A8gnes?= <514737+acogoluegnes@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:00:55 +0200 Subject: [PATCH] Initialize frame handler's connection reference before sending header _frameHandler.sendHeader() can trigger an immediate reply from the broker, which the I/O thread processes as soon as it arrives. If that happens before _frameHandler.initialize(this) has run, the I/O thread dereferences a still-null AMQConnection reference (e.g. in AmqpHandler.channelRead for the Netty transport) and the connection fails with a NullPointerException wrapped as an IOException. This mostly surfaces under CI-style thread scheduling on fast/local round-trips, where the reply can outrace initialize(). --- src/main/java/com/rabbitmq/client/impl/AMQConnection.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/rabbitmq/client/impl/AMQConnection.java b/src/main/java/com/rabbitmq/client/impl/AMQConnection.java index dfaa8989e..6eb181c6a 100644 --- a/src/main/java/com/rabbitmq/client/impl/AMQConnection.java +++ b/src/main/java/com/rabbitmq/client/impl/AMQConnection.java @@ -321,6 +321,10 @@ public void start() // initiator) is to wait for a connection.start method to // arrive. _channel0.enqueueRpc(connStartBlocker); + // Must happen before the header is sent: sending it can make the broker reply + // immediately, and the I/O thread that reads that reply needs the connection + // reference to already be in place, or it hits a null reference. + this._frameHandler.initialize(this); try { // The following two lines are akin to AMQChannel's // transmit() method for this pseudo-RPC. @@ -331,8 +335,6 @@ public void start() throw ioe; } - this._frameHandler.initialize(this); - AMQP.Connection.Start connStart; AMQP.Connection.Tune connTune = null; try {