Poison-message handling
Some messages will never succeed — malformed content, a reference that no longer exists, a bug they trigger every time. Left in place, one poison message retries forever and blocks everything behind it. The fix is to recognise it and set it aside.
A poison message is different from a transient failure: retrying it does not help, because the problem is the message itself, not the endpoint. After a bounded number of failed attempts, it is pulled out of the normal flow to a dead-letter store — intact and inspectable — so the queue behind it keeps moving.
The best defence is to catch poison early — validate at the edge so malformed input is rejected on arrival rather than discovered three steps in. What slips past validation is caught here, and either way the message is preserved for a fix and replay, never dropped.
In Art2link the threshold is the send adapter’s Retries count. A message that fails every attempt exhausts it; with Exception enabled on the port, that exhausted message is re-published under the exception message type instead of being attempted forever, so it stops blocking the traffic behind it. A dead-letter send port subscribes to that type and stores it for inspection:
{{Message.MessageType}} == "OrderSendFailed"The difference from a transient failure is only the outcome: a transient error clears within the retry budget, while a poison message never does — so the exception path carries it out of the flow for inspection and, if it was a fixable defect, replay.