On 4/7/26 13:43, Artem Bilan via users wrote:
I think I have figured it out.
After gathering RabbitMQ logs I got this clue:

2026-04-07 16:59:02.368622+00:00 [info] <0.821.0> Connection from AMQP 1.0
container 'ID:7629abd0-e49d-4c5a-826f-7dbc19e0a9d4:2:1': user 'guest'
authenticated using SASL mechanism ANONYMOUS and granted access to vhost '/'
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> Received Flow frame
for unknown link handle: {'v1_0.flow',
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> {uint,1},
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> {uint,1600},
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> {uint,1},
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> {uint,2147483647},
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> {uint,1},
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> {uint,0},
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> {uint,0},
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0>
undefined,false,undefined,
2026-04-07 16:59:02.390733+00:00 [warning] <0.827.0> undefined}
2026-04-07 16:59:02.390983+00:00 [warning] <0.827.0> Closing session for
connection <0.821.0>: {'v1_0.error',
2026-04-07 16:59:02.390983+00:00 [warning] <0.827.0> {symbol,
2026-04-07 16:59:02.390983+00:00 [warning] <0.827.0>
<<"amqp:session:unattached-handle">>},
2026-04-07 16:59:02.390983+00:00 [warning] <0.827.0> {utf8,
2026-04-07 16:59:02.390983+00:00 [warning] <0.827.0> <<"Unattached link
handle: 1">>},
2026-04-07 16:59:02.390983+00:00 [warning] <0.827.0> undefined}
So, looks like we are trying to interact with a link which is not fully
ready on the broker side.

Therefore I went forward and implemented reaction to this API:

/**
  * @return a {@link Future} that will be completed when the remote
opens this {@link Link}.
  */
Future<T> openFuture();

Something like this, for example:

senderToReturn =
        this.connectionFactory
              .getConnection()
              .openAnonymousSender(this.senderOptions);
Future<Sender> openFuture = senderToReturn.openFuture();
this.sender = ProtonUtils.toSupplier(openFuture,
this.senderOptions.openTimeout()).get();

So far my tests are OK.

I think this ticket can be closed.

Thank you for your support!

Glad you are able to work past it, although it sounds as though there's a bug in the broker that should be reported.





On Tue, Mar 31, 2026 at 2:03 PM Artem Bilan <[email protected]>
wrote:

I'm still investigating the cause of premature and sproradic session
closure in my tests.
However I want to point that RabbitMQ does support several links per
session.
My original impression was wrong.
Either way need to figure out how to pull RabbitMQ logs from
Testcontainers when that test fails.

On Mon, Mar 30, 2026 at 2:36 PM Timothy Bish <[email protected]> wrote:

I don't really know anything about the RabbitMQ implementation so I
cannot really provide any insights into why it closed the session but I
would guess that is the cause of your failed test, it might be sporadic due
to this being something that happens after your  test is done or in the
process of closing down so it only gets seems sometimes.

This is where your session was closed by the remote so I'd suggest
looking into why you might get the specific error and session closure.
<- AMQP:[310426339:0]
End{error=Error{condition=amqp:session:unattached-handle,
description='Unattached link handle: 2', info=null}}
-> AMQP:[310426339:0] End{error=null}

The protonj2 client allows you to manage sessions as you like so if
Rabbit needs a session per producer or consumer that is definitely
something you can do, if you are using the connection level APIs to create
them you would already be using a single session for the entirety of the
connection's resources.

On Mon, Mar 30, 2026 at 1:05 PM Artem Bilan via users <
[email protected]> wrote:

Hi Tim!
Thank you for the tip!
I added that tracing for frames, however it does not say me too much.
Just test sporadically fails like with this trace:

-> SASL:[310426339:0] AMQP,3,1,0,0
<- SASL:[310426339:0] AMQP,3,1,0,0
<- SASL:[310426339:0] SaslMechanisms{saslServerMechanisms=[PLAIN,
AMQPLAIN, ANONYMOUS]}
2026-03-28 05:35:21,659 WARN
org.apache.qpid.protonj2.engine.sasl.client.SaslMechanismSelector
[ClientConnection :(ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1): I/O
Thread] : Caught exception while trying to create SASL mechanism AMQPLAIN:
No Matching SASL Mechanism with name: AMQPLAIN
-> SASL:[310426339:0] SaslInit{mechanism=ANONYMOUS, initialResponse="",
hostname='localhost'}
<- SASL:[310426339:0] SaslOutcome{code=OK, additionalData=null}
-> AMQP:[310426339:0] AMQP,0,1,0,0
<- AMQP:[310426339:0] AMQP,0,1,0,0
-> AMQP:[310426339:0] Open{
containerId='ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1',
hostname='localhost', maxFrameSize=65536, channelMax=65535,
idleTimeOut=30000, outgoingLocales=null, incomingLocales=null,
offeredCapabilities=null, desiredCapabilities=[ANONYMOUS-RELAY],
properties=null}
-> AMQP:[310426339:0] Begin{remoteChannel=null, nextOutgoingId=0,
incomingWindow=1600, outgoingWindow=2147483647, handleMax=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[310426339:0]
Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1',
handle=0, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=LINK_DETACH, timeout=0, dynamic=false,
dynamicNodeProperties=null, distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=SESSION_END, timeout=0, dynamic=false,
dynamicNodeProperties=null, capabilities=null}, unsettled=null,
incompleteUnsettled=null, initialDeliveryCount=null, maxMessageSize=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[310426339:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=0, deliveryCount=null,
linkCredit=55, available=null, drain=false, echo=null, properties=null}
-> AMQP:[310426339:0]
Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:2',
handle=1, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=LINK_DETACH, timeout=0, dynamic=false,
dynamicNodeProperties=null, distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=SESSION_END, timeout=0, dynamic=false,
dynamicNodeProperties=null, capabilities=null}, unsettled=null,
incompleteUnsettled=null, initialDeliveryCount=null, maxMessageSize=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[310426339:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=1, deliveryCount=null,
linkCredit=55, available=null, drain=false, echo=null, properties=null}
-> AMQP:[310426339:0]
Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:3',
handle=2, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=LINK_DETACH, timeout=0, dynamic=false,
dynamicNodeProperties=null, distributionMode=null, filter=null,
defaultOutcome=Modified{deliveryFailed=true, undeliverableHere=false,
messageAnnotations=null}, outcomes=[amqp:accepted:list, amqp:rejected:list,
amqp:released:list, amqp:modified:list], capabilities=null},
target=Target{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=SESSION_END, timeout=0, dynamic=false,
dynamicNodeProperties=null, capabilities=null}, unsettled=null,
incompleteUnsettled=null, initialDeliveryCount=null, maxMessageSize=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[310426339:0] Flow{nextIncomingId=null, incomingWindow=1600,
nextOutgoingId=0, outgoingWindow=2147483647, handle=2, deliveryCount=null,
linkCredit=55, available=null, drain=false, echo=null, properties=null}
<- AMQP:[310426339:0] Open{ containerId='rabbit@69e87c0daa99',
hostname='null', maxFrameSize=131072, channelMax=63, idleTimeOut=30000,
outgoingLocales=null, incomingLocales=null,
offeredCapabilities=[LINK_PAIR_V1_0, ANONYMOUS-RELAY],
desiredCapabilities=null, properties={node=rabbit@69e87c0daa99,
cluster_name=rabbit@69e87c0daa99, copyright=Copyright (c) 2007-2026
Broadcom Inc and/or its subsidiaries, information=Licensed under the MPL
2.0. Website: https://rabbitmq.com, platform=Erlang/OTP 27.3.4.9,
product=RabbitMQ, version=4.2.5}}
<- AMQP:[310426339:0] Begin{remoteChannel=0, nextOutgoingId=0,
incomingWindow=400, outgoingWindow=4294967295, handleMax=255,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
-> AMQP:[310426339:0]
Attach{name='sender-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1',
handle=3, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='null', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null, defaultOutcome=null,
outcomes=[amqp:accepted:list, amqp:rejected:list, amqp:released:list,
amqp:modified:list], capabilities=null}, target=Target{address='null',
durable=NONE, expiryPolicy=SESSION_END, timeout=0, dynamic=false,
dynamicNodeProperties=null, capabilities=null}, unsettled=null,
incompleteUnsettled=null, initialDeliveryCount=0, maxMessageSize=null,
offeredCapabilities=null, desiredCapabilities=null, properties=null}
<- AMQP:[310426339:0]
Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1',
handle=0, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=LINK_DETACH, timeout=0, dynamic=false,
dynamicNodeProperties=null, distributionMode=null, filter=null,
defaultOutcome=Released{}, outcomes=[amqp:accepted:list,
amqp:rejected:list, amqp:released:list, amqp:modified:list],
capabilities=null}, target=null, unsettled=null, incompleteUnsettled=null,
initialDeliveryCount=0, maxMessageSize=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[310426339:0]
Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:2',
handle=1, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=LINK_DETACH, timeout=0, dynamic=false,
dynamicNodeProperties=null, distributionMode=null, filter=null,
defaultOutcome=Released{}, outcomes=[amqp:accepted:list,
amqp:rejected:list, amqp:released:list, amqp:modified:list],
capabilities=null}, target=null, unsettled=null, incompleteUnsettled=null,
initialDeliveryCount=0, maxMessageSize=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[310426339:0]
Attach{name='receiver-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:3',
handle=2, role=SENDER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='/queues/enable_amqp_queue1', durable=NONE,
expiryPolicy=LINK_DETACH, timeout=0, dynamic=false,
dynamicNodeProperties=null, distributionMode=null, filter=null,
defaultOutcome=Released{}, outcomes=[amqp:accepted:list,
amqp:rejected:list, amqp:released:list, amqp:modified:list],
capabilities=null}, target=null, unsettled=null, incompleteUnsettled=null,
initialDeliveryCount=0, maxMessageSize=null, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[310426339:0]
Attach{name='sender-ID:a54be302-d329-4598-8bfc-55b1cfed2e33:1:1:1:1',
handle=3, role=RECEIVER, sndSettleMode=UNSETTLED, rcvSettleMode=FIRST,
source=Source{address='null', durable=NONE, expiryPolicy=LINK_DETACH,
timeout=0, dynamic=false, dynamicNodeProperties=null,
distributionMode=null, filter=null, defaultOutcome=null,
outcomes=[amqp:accepted:list, amqp:rejected:list, amqp:released:list,
amqp:modified:list], capabilities=null}, target=Target{address='null',
durable=NONE, expiryPolicy=SESSION_END, timeout=0, dynamic=false,
dynamicNodeProperties=null, capabilities=null}, unsettled=null,
incompleteUnsettled=null, initialDeliveryCount=null,
maxMessageSize=16777216, offeredCapabilities=null,
desiredCapabilities=null, properties=null}
<- AMQP:[310426339:0] Flow{nextIncomingId=0, incomingWindow=400,
nextOutgoingId=0, outgoingWindow=4294967295, handle=3, deliveryCount=0,
linkCredit=170, available=null, drain=null, echo=null, properties=null}
-> AMQP:[310426339:0] Transfer{handle=3, deliveryId=0, deliveryTag={0},
messageFormat=0, settled=false, more=false, rcvSettleMode=null, state=null,
resume=null, aborted=null, batchable=null} -
"\x00Sp\xc0\x04\x02AP\x00\x00Ss\xd0\x00\x00\x00B\x00\x00\x00\x0a@
"...(truncated)
<- AMQP:[310426339:0] Transfer{handle=0, deliveryId=0,
deliveryTag=DeliveryTag: {[0, 0, 0, 0]}, messageFormat=0, settled=false,
more=false, rcvSettleMode=null, state=null, resume=null, aborted=null,
batchable=null} - "\x00Sp\xc0\x07\x05AP\x00@AC
\x00Sr\xc12\x04\xa3\x0ax-exchange\xa1"...(truncated)
<- AMQP:[310426339:0] Disposition{role=RECEIVER, first=0, last=0,
settled=true, state=Accepted{}, batchable=false}
-> AMQP:[310426339:0] Flow{nextIncomingId=1, incomingWindow=1600,
nextOutgoingId=1, outgoingWindow=2147483647, handle=0, deliveryCount=1,
linkCredit=0, available=null, drain=false, echo=null, properties=null}
-> AMQP:[310426339:0] Detach{handle=0, closed=true, error=null}
-> AMQP:[310426339:0] Flow{nextIncomingId=1, incomingWindow=1600,
nextOutgoingId=1, outgoingWindow=2147483647, handle=1, deliveryCount=0,
linkCredit=0, available=null, drain=false, echo=null, properties=null}
<- AMQP:[310426339:0] Detach{handle=0, closed=true, error=null}
-> AMQP:[310426339:0] Flow{nextIncomingId=1, incomingWindow=1600,
nextOutgoingId=1, outgoingWindow=2147483647, handle=2, deliveryCount=0,
linkCredit=0, available=null, drain=false, echo=null, properties=null}
<- AMQP:[310426339:0] Transfer{handle=1, deliveryId=1,
deliveryTag=DeliveryTag: {[0, 0, 0, 0]}, messageFormat=0, settled=false,
more=false, rcvSettleMode=null, state=null, resume=null, aborted=null,
batchable=null} - "\x00Sp\xc0\x07\x05AP\x00@BC
\x00Sr\xc12\x04\xa3\x0ax-exchange\xa1"...(truncated)
-> AMQP:[310426339:0] Detach{handle=2, closed=true, error=null}
<- AMQP:[310426339:0] Detach{handle=2, closed=true, error=null}
-> AMQP:[310426339:0] Detach{handle=1, closed=true, error=null}
<- AMQP:[310426339:0]
End{error=Error{condition=amqp:session:unattached-handle,
description='Unattached link handle: 2', info=null}}
-> AMQP:[310426339:0] End{error=null}
I don't know if that is the case, but might be that RabbitMQ requires
explicit session management for consumer and/or producers.
At the same time I saw somewhere that some AMQP brokers requires one
session per connection...
I might consider to add a session management into my components if that
is the case.

Any thoughts?

Thank you very much!

On 2026/03/26 14:40:32 Timothy Bish wrote:
On 3/25/26 11:59, Artem Bilan via users wrote:
Hi there!

I am developing Spring Framework client based on the QPid ProtonJ 2
Client:

https://github.com/spring-projects/spring-amqp/tree/main/spring-amqp-client/src
.
One of my tests is sporadically failing like:
Without an AMQP frame trace it is not possible to say why this is
failing, it is valid for the error to occur if the session is remotely
closed. The configuration guide in the docs explains how to enable
frame
tracing, with that enabled you can see the frames that arrived around
the time this error occurs.


https://github.com/apache/qpid-protonj2/blob/main/protonj2-client-docs/Configuration.md#logging

Caused by: java.lang.IllegalStateException: Cannot create new
Receiver
from closed Session


at

org.apache.qpid.protonj2.engine.impl.ProtonSession.checkSessionClosed(ProtonSession.java:670)


at

org.apache.qpid.protonj2.engine.impl.ProtonSession.receiver(ProtonSession.java:396)


at

org.apache.qpid.protonj2.engine.impl.ProtonSession.receiver(ProtonSession.java:59)


at

org.apache.qpid.protonj2.client.impl.ClientReceiverBuilder.createReceiver(ClientReceiverBuilder.java:142)


at

org.apache.qpid.protonj2.client.impl.ClientReceiverBuilder.receiver(ClientReceiverBuilder.java:61)


at

org.apache.qpid.protonj2.client.impl.ClientSession.internalOpenReceiver(ClientSession.java:391)


at

org.apache.qpid.protonj2.client.impl.ClientConnection.lambda$openReceiver$3(ClientConnection.java:279)


at

io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:148)


at

io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:141)


at

io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:535)


at
io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:405)
at

io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:1195)


at

io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)

I have a single connection object per test suite lifecycle.
The code I try to create a Receiver is like:
ClientReceiver receiver =

(ClientReceiver)connection.openReceiver(queue,receiverOptions)
               .addCredit(this.initialCredits);
Which apparently leads to the shared internal session in that
connection.
The broker I test against is RabbitMQ 4.2.

So, the question is: if I'm doing something wrong or missing
anything.
I also do have a reconnectEnabled on the connection.

Please, let me know if you need anything else.

Thank you!

Regards,
Artem Bilan

--
Tim Bish


--
--
Tim Bish



--
Tim Bish


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to