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 > > >
