Handling poison messages in IBM WebSphere MQ classes for JMS

A poison message is one which cannot be processed by a receiving MDB application. If a poison message is encountered, the JMS MessageConsumer and ConnectionConsumer objects can requeue it according to two queue properties, BOQNAME, and BOTHRESH.

Sometimes, a badly formatted message arrives on a queue. In this context, badly formatted means that the receiving application cannot process the message correctly. Such a message can cause the receiving application to fail and to back out this badly formatted message. The message can then be repeatedly delivered to the input queue and repeatedly backed out by the application. These messages are known as poison messages. The JMS MessageConsumer object detects poison messages and reroutes them to an alternative destination.

The IBM® WebSphere® MQ queue manager keeps a record of the number of times that each message has been backed out. When this number reaches a configurable threshold value, the message consumer requeues the message to a named backout queue. If this requeuing fails for any reason, the message is removed from the input queue and either requeued to the dead-letter queue, or discarded. See Removing messages from the queue in ASF for more details.

There is a difference between the way in which poison messages are requeued by MessageConsumers and ConnectionConsumers. ConnectionConsumers are able to requeue poison messages without affecting message delivery. The requeue process takes place outside of any unit of work associated with actual message delivery to application code. This is possible because of the multi-threaded nature of ConnectionConsumer operation.

MessageConsumers, however, are single threaded below the Session level, and any requeuing of poison messages takes place within the current unit of work. This does not affect the operation of the application, however when poison messages are requeued under a transacted or Client_acknowledge Session, the requeue action itself is not committed until the current unit of work is committed by the application code or, if appropriate, the application container code.

JMS ConnectionConsumer objects handle poison messages in the same way and using the same queue properties. If multiple connection consumers are monitoring the same queue, it is possible that the poison message may be delivered to an application more times than the threshold value before the requeue occurs. This behavior is due to the way individual connection consumers monitor queues and requeue poison messages.

The threshold value and the name of the back out queue are attributes of an IBM WebSphere MQ queue. The names of the attributes are BackoutThreshold and BackoutRequeueQName. The queue they apply to is as follows:
  • For point-to-point messaging, this is the underlying local queue. This is important when message consumers and connection consumers use queue aliases.
  • For publish/subscribe messaging in IBM WebSphere MQ messaging provider normal mode, the Topic's managed queue is created from the model queue.
  • For publish/subscribe messaging in IBM WebSphere MQ messaging provider migration mode, it is the CCSUB queue defined on the TopicConnectionFactory object, or the CCDSUB queue defined on the Topic object.
IBM WebSphere MQ classes for JMS queries the BackoutThreshold and BackoutRequeueQName of the queue. You must therefore grant inquire access on the queue to the user running the application.
[V7.5.0.9 Sep 2018]If the target queue is a cluster queue, then the authorities needed depend on the version of the IBM WebSphere MQ classes for JMS being used:
  • When using the IBM WebSphere MQ classes for JMS for Version 7.5.0, Fix Pack 9 plus an interim fix for APAR IT26482, inquire access is required.
  • For all other versions, grant inquire, browse and get access.
To set the BackoutThreshold and BackoutRequeueQName attributes, issue the following MQSC command:
ALTER QLOCAL(your.queue.name) BOTHRESH(threshold value) BOQNAME(your.backout.queue.name)

If the BackoutThreshold attribute is set to a value other than zero, to avoid unexpected behavior set the BackoutRequeueQName attribute to a valid queue name.

For publish/subscribe messaging, if your system creates a dynamic queue for each subscription, these attribute values are obtained from the IBM WebSphere MQ classes for JMS model queue, SYSTEM.JMS.MODEL.QUEUE. To alter these settings, use:
ALTER QMODEL(SYSTEM.JMS.MODEL.QUEUE) BOTHRESH(threshold value) BOQNAME(your.backout.queue.name)

If the backout threshold value is zero, poison message handling is disabled, and poison messages remain on the input queue. Otherwise, when the backout count reaches the threshold value, the message is sent to the named backout queue. If the backout count reaches the threshold value, but the message cannot go to the backout queue, the message is sent to the dead-letter queue or it is discarded. This situation occurs if the backout queue is not defined, or if the MessageConsumer object cannot send the message to the backout queue. See Removing messages from the queue in ASF for further details.

When a message is requeued to the backout requeue queue, some of the field values in the Message Descriptor (MQMD) of the message change. See MQMD - Message Descriptor for details about the format of the MQMD.

The following MQMD fields change value when the message goes onto the backout queue.
  • PutDate is updated to the date it goes onto the backout requeue queue.
  • PutTime is updated to the time it goes onto the backout requeue queue.
  • Backout count is reset to zero.
  • Expiry of the message is updated to reflect the remaining expiry at the time the original message was received by the JMS application.
The values in the following fields stay the same when the message goes onto the backout queue:
  • StructId
  • Version
  • Report
  • MessageType
  • Feedback
  • Encoding
  • CodedCharSetId
  • MsgId
  • CorrelId
  • ReplyToQ
  • ReplyToQMgr
  • Format
  • Persistence
  • Priority