Retry & Dead Letter Queue
What happens when a handler throws.
Immediate retries — when a handler throws, the message broker/framework retries processing right away, a few times, for transient failures (a brief DB blip, a momentary network error) that are likely to succeed on the very next attempt.
Delayed/exponential-backoff retries — if immediate retries are exhausted, wait progressively longer between further attempts (e.g. 10s, then 1min, then 10min) — for failures that need more time to resolve (a downstream service restarting, a rate limit cooling down) rather than hammering it instantly N more times.
Dead Letter Queue (DLQ) — after all retry policies are exhausted, the message is moved to a separate queue instead of being silently dropped or retried forever. This is critical: it preserves the message for inspection/manual intervention/replay, and — just as importantly — stops one poison message from blocking the whole queue behind it forever. NServiceBus calls this its error queue; the underlying idea is identical to RabbitMQ/Azure Service Bus DLQs.
What you should actually say if asked "how would you handle a message that keeps failing": separate transient failures (network blip — retry) from permanent ones (malformed message, business rule that will never pass — no amount of retrying fixes a poison message), and make sure the poison message ends up in a DLQ with enough context (the original message + the exception) to diagnose it later, rather than being retried forever or silently swallowed.