Thank you for the explanation. I better understand now. And I think
switching to regular consumers will probably work.

Thanks again.

On Tue, Mar 10, 2026 at 7:53 PM Timothy Bish <[email protected]> wrote:

> On 3/10/26 21:29, John wrote:
> > Yes, you are correct. I've confirmed that we are using Artemis for the
> > subscriptions. ActiveMQ is being used for other purposes. The exception
> > from earlier was when using Artemis.
> >
> > So to me, this means it's a bug. If the Client IDs are the same, an
> > exception is thrown when Artemis is used as the broker. Would the
> > developers be interested in looking into this? If so, how should we
> submit
> > the issue to them?
> >
> > Thanks
>
> Sorry I was unclear earlier as I was in a rush and I misled you a bit.
>
> A JMS client if setting a client ID must give a unique ID which is why
> you got the error shown as your clients are all trying to connect with
> the same client ID.  This is the issue though that prevents you from
> using shared subscriptions in they way you want since if you set client
> IDs the shared subscriptions cannot be shared across connections, only
> from consumers created by sessions under the same connection.  Think of
> the client ID as a namespace and the lack of one as a global namespace.
> Shared subscriptions will work for you if your clients do not set a
> client ID as you've seen because the namespace of all shared
> subscriptions without a client ID is shared as a global namespace for
> that subscription across connections.  Once you set a client ID you are
> effectively in a private namespace owned by the connection that set that
> ID and no two connections can share the same client ID.
>
> ActiveMQ does not implement shared subscriptions at all so if you try to
> use those APIs from the NMS client against that broker the result will
> likely be an error response or something not doing what you want so you
> need to use Apache Artemis if you want shared subscriptions but you will
> need to stick to no client ID if you want to share across connections.
> Likely you can accomplish what you want by simply moving to using a
> Queue as consumers on a Queue all compete for messages (work sharing)
> which seems like what you are going for. but your exact requirements
> wasn't fully clear so you'd need to provide more info on why you want to
> use shared subs.
>
>
> >
> > On Tue, Mar 10, 2026 at 5:33 PM Timothy Bish <[email protected]>
> wrote:
> >
> >> On 3/10/26 20:15, John wrote:
> >>> Thank you for your reply.
> >>>
> >>> If I understand correctly, we should use the same client ID for each
> >>> client. And, if that is the case, then this has already been tried,
> >>> and the result is that every client after the first throws this
> >>> exception:
> >> I know that ActiveMQ doesn't support shared subscriptions of any sort so
> >> if you tried this with ActiveMQ you will not get anything to work, and
> >> if it did somehow create a subscription it would not be a valid one.
> >> You would need to use Apache Artemis for shared subscription support as
> >> that has full support for the AMQP JMS mapping.  As the specification
> >> states the subscription is named by the subscription name and the client
> >> ID so if you want to share your clients either need no client ID or they
> >> all need the same for the subscription in question.
> >>
> >>
> >>> Unhandled exception. Apache.NMS.NMSException: , ErrorInfo = {
> >>> key: invalid-field, value: container-id;
> >>> }
> >>>    ---> Apache.NMS.AMQP.Util.NMSProviderError: amqp:invalid-field
> >>>      at Apache.NMS.AMQP.Util.ExceptionSupport.GetException(Error
> >>> amqpErr, String message, Exception e)
> >>>      at
> Apache.NMS.AMQP.Provider.Amqp.AmqpConnection.OnClosed(IAmqpObject
> >>> sender, Error error)
> >>>      at Amqp.AmqpObject.NotifyClosed(Error error)
> >>>      at Amqp.Connection.OnEnded(Error error)
> >>>      at Amqp.Connection.OnClose(Close close)
> >>>      at Amqp.Connection.OnFrame(ByteBuffer buffer)
> >>>      at Amqp.AsyncPump.PumpAsync(UInt32 maxFrameSize, Func`2 onHeader,
> >>> Func`2 onBuffer)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object
> >>> s)
> >>>      at System.Threading.ExecutionContext.RunInternal(ExecutionContext
> >>> executionContext, ContextCallback callback, Object state)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread
> >>> threadPoolThread)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
> >>>      at
> >>
> System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action
> >>> innerContinuation, Task innerTask)
> >>>      at
> >> System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action
> >>> action, Boolean allowInlining)
> >>>      at System.Threading.Tasks.Task.RunContinuations(Object
> >> continuationObject)
> >>>      at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1
> >>> task, TResult result)
> >>>      at Amqp.AsyncPump.ReceiveBufferAsync(Byte[] buffer, Int32 offset,
> >>> Int32 count)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object
> >>> s)
> >>>      at System.Threading.ExecutionContext.RunInternal(ExecutionContext
> >>> executionContext, ContextCallback callback, Object state)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread
> >>> threadPoolThread)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
> >>>      at
> >>
> System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action
> >>> innerContinuation, Task innerTask)
> >>>      at
> >> System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action
> >>> action, Boolean allowInlining)
> >>>      at System.Threading.Tasks.Task.RunContinuations(Object
> >> continuationObject)
> >>>      at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(Task`1
> >>> task, TResult result)
> >>>      at
> >> Amqp.TcpTransport.TcpSocket.Amqp.IAsyncTransport.ReceiveAsync(Byte[]
> >>> buffer, Int32 offset, Int32 count)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.ExecutionContextCallback(Object
> >>> s)
> >>>      at System.Threading.ExecutionContext.RunInternal(ExecutionContext
> >>> executionContext, ContextCallback callback, Object state)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext(Thread
> >>> threadPoolThread)
> >>>      at
> >>
> System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
> >>>      at
> >>
> System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action
> >>> innerContinuation, Task innerTask)
> >>>      at
> >> System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action
> >>> action, Boolean allowInlining)
> >>>      at System.Threading.Tasks.Task.RunContinuations(Object
> >> continuationObject)
> >>>      at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
> >>>      at
> >> System.Threading.Tasks.TaskCompletionSource`1.TrySetResult(TResult
> result)
> >>>      at Amqp.SocketExtensions.Complete[T](Object sender,
> >>> SocketAsyncEventArgs args, Boolean throwOnError, T result)
> >>>      at Amqp.TcpTransport.TcpSocket.<>c.<.ctor>b__6_1(Object s,
> >>> SocketAsyncEventArgs a)
> >>>      at System.Threading.ExecutionContext.RunInternal(ExecutionContext
> >>> executionContext, ContextCallback callback, Object state)
> >>>      at
> >> System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__174_0(UInt32
> >>> errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
> >>>      at
> >> System.Threading.PortableThreadPool.IOCompletionPoller.Event.Invoke()
> >>>      at
> >>
> System.Threading.ThreadPoolTypedWorkItemQueue.System.Threading.IThreadPoolWorkItem.Execute()
> >>>      at System.Threading.ThreadPoolWorkQueue.Dispatch()
> >>>      at
> >> System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
> >>>      at System.Threading.Thread.StartCallback()
> >>>
> >>>      --- End of inner exception stack trace ---
> >>>      at
> Apache.NMS.AMQP.NmsConnection.CreateNmsConnectionInternal(Boolean
> >> sync)
> >>>      at
> >>
> Apache.NMS.AMQP.Util.Synchronization.TaskExtensions.AwaitRunContinuationAsync(Task
> >>> task)
> >>>      at Apache.NMS.AMQP.NmsConnection.StartAsync()
> >>>      at
> >> Apache.NMS.AMQP.Util.Synchronization.TaskExtensions.GetAsyncResult(Task
> >>> task)
> >>>      at Apache.NMS.AMQP.NmsConnection.Start()
> >>>
> >>>
> >>>
> >>>
> >>> On Tue, Mar 10, 2026 at 4:48 PM Timothy Bish <[email protected]>
> >> wrote:
> >>>> On 3/10/26 19:42, John wrote:
> >>>>> Hi Tim,
> >>>>>
> >>>>> Yes, each client has a unique Client ID. And this has been verified.
> >>>>> However, should the Client ID follow a specific pattern?
> >>>> That's your problem then, you are creating many uniquely identified
> >>>> shared subscriptions.
> >>>>
> >>>>    From the JMS specification
> >>>>
> >>>> "A shared non-durable subscription is identified by a name specified
> by
> >>>> the client and by the client
> >>>> identifier if set. If the client identifier was set when the shared
> >>>> non-durable subscription was first
> >>>> created then a client which subsequently wishes to create a consumer
> on
> >>>> that shared non-durable
> >>>> subscription must use the same client identifier."
> >>>>
> >>>>
> >>>>> On Tue, Mar 10, 2026 at 4:17 PM Timothy Bish <[email protected]>
> >> wrote:
> >>>>>> On 3/10/26 18:51, John wrote:
> >>>>>>> Hi,
> >>>>>>>
> >>>>>>> I have stumbled across an issue that I believe is with
> >> Apache.NMS.AMQP
> >>>>>>> library. I'm using the latest stable version, 2.4.0, for my .NET C#
> >>>>>> service
> >>>>>>> for message handling, with the latest Apache Artemis and Apache
> >> ActiveMQ
> >>>>>>> message brokers.
> >>>>>>> Both the web page on Uri Configuration (
> >>>>>>>
> >>
> https://activemq.apache.org/components/nms/providers/amqp/uri-configuration
> >>>>>> )
> >>>>>>> and the GitHub project (
> >>>>>>>
> >>
> https://github.com/apache/activemq-nms-amqp/blob/main/docs/configuration.md
> >>>>>> )
> >>>>>>> state that "nms.clientId" should be used in the Connection Uri to
> >>>>>> configure
> >>>>>>> the Client ID.
> >>>>>>> However, I have found that using "nms.clientId" breaks consumer
> >>>>>>> functionality for Shared Consumers, who will then receive every
> >> message
> >>>>>> in
> >>>>>>> the topic. And that, excluding the query parameter, allows Shared
> >>>>>> Consumers
> >>>>>>> to function correctly, with each consumer receiving only their
> share
> >> of
> >>>>>> the
> >>>>>>> messages.
> >>>>>>> Please also note that if one does not include the parameter in the
> >> Uri
> >>>>>> but
> >>>>>>> instead sets the ClientId on the connection object itself, the
> Shared
> >>>>>>> Customer will still not function correctly, having the same issue
> as
> >>>>>> using
> >>>>>>> the parameter in the Uri.
> >>>>>>> However, by not including the nms.clientId parameter, a Client ID
> is
> >>>>>>> automatically generated, which I guess is why it works correctly.
> >>>>>>> Nevertheless, it is less than ideal not being able to use my own
> >> Client
> >>>>>> ID.
> >>>>>>> But maybe I'm doing something wrong. Here is some simple example
> code
> >>>>>> using
> >>>>>>> the nms.clientId parameter that has the issue:
> >>>>>>>
> >>>>>>> static async Task SharedAsync(string clientId, CancellationToken
> >>>>>>> stoppingToken)
> >>>>>>> {
> >>>>>>>         string uri =
> >>>>>>>
> >>
> $"amqp://localhost:61616?nms.username=artemis&nms.password=artemis&nms.clientId={clientId}";
> >>>>>> Are you giving each client the same ID or are they each being
> assigned
> >>>>>> there own unique client ID ?
> >>>>>>
> >>>>>>
> >>>>>>>         var connecturi = new Uri(uri);
> >>>>>>>         var factory = new NMSConnectionFactory(connecturi);
> >>>>>>>         using IConnection connection = await
> >>>>>> factory.CreateConnectionAsync();
> >>>>>>>         connection.Start();
> >>>>>>>         using ISession session = await
> >> connection.CreateSessionAsync();
> >>>>>>>         ITopic destination = await
> >> session.GetTopicAsync("topic-name");
> >>>>>>>         using var consumer = await
> >>>>>>> session.CreateSharedConsumerAsync(destination, "sub-name");
> >>>>>>>         while (!stoppingToken.IsCancellationRequested)
> >>>>>>>         {
> >>>>>>>             var msg = await
> >>>>>>> consumer.ReceiveAsync(TimeSpan.FromMicroseconds(250)) as
> >> ITextMessage;
> >>>>>>>             if (msg is not null)
> >>>>>>>             {
> >>>>>>>                 // process message
> >>>>>>>             }
> >>>>>>>         }
> >>>>>>> }
> >>>>>>>
> >>>>>>>
> >>>>>>> Thanks,
> >>>>>>> John
> >>>>>>>
> >>>>>> --
> >>>>>> Tim Bish
> >>>>>>
> >>>>>>
> >>>>>>
> ---------------------------------------------------------------------
> >>>>>> To unsubscribe, e-mail: [email protected]
> >>>>>> For additional commands, e-mail: [email protected]
> >>>>>> For further information, visit: https://activemq.apache.org/contact
> >>>>>>
> >>>>>>
> >>>>>>
> >>>> --
> >>>> Tim Bish
> >>>>
> >>>>
> >>>> ---------------------------------------------------------------------
> >>>> To unsubscribe, e-mail: [email protected]
> >>>> For additional commands, e-mail: [email protected]
> >>>> For further information, visit: https://activemq.apache.org/contact
> >>>>
> >>>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: [email protected]
> >>> For additional commands, e-mail: [email protected]
> >>> For further information, visit: https://activemq.apache.org/contact
> >>>
> >>>
> >> --
> >> Tim Bish
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [email protected]
> >> For additional commands, e-mail: [email protected]
> >> For further information, visit: https://activemq.apache.org/contact
> >>
> >>
> >>
>
> --
> Tim Bish
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> For further information, visit: https://activemq.apache.org/contact
>
>
>

Reply via email to