This is an automated email from the ASF dual-hosted git repository.

chibenwa pushed a commit to branch dlx-deleted-message-vault
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit dad2a9af619a0faf52ea9c3e74dacba9aa608d78
Author: Benoit TELLIER <[email protected]>
AuthorDate: Mon Jun 29 17:11:27 2026 +0200

    [FIX] Dead letter setup for Deleted Message Vault
---
 .../DistributedDeletedMessageVaultDeletionCallback.java     | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git 
a/server/container/guice/distributed/src/main/java/org/apache/james/modules/mailbox/DistributedDeletedMessageVaultDeletionCallback.java
 
b/server/container/guice/distributed/src/main/java/org/apache/james/modules/mailbox/DistributedDeletedMessageVaultDeletionCallback.java
index d848c037c1..1385547c55 100644
--- 
a/server/container/guice/distributed/src/main/java/org/apache/james/modules/mailbox/DistributedDeletedMessageVaultDeletionCallback.java
+++ 
b/server/container/guice/distributed/src/main/java/org/apache/james/modules/mailbox/DistributedDeletedMessageVaultDeletionCallback.java
@@ -197,6 +197,9 @@ public class DistributedDeletedMessageVaultDeletionCallback 
implements DeleteMes
                 sender.declareExchange(ExchangeSpecification.exchange(EXCHANGE)
                     .durable(DURABLE)
                     .type(DIRECT_EXCHANGE)),
+                
sender.declareExchange(ExchangeSpecification.exchange(DEAD_LETTER)
+                    .durable(DURABLE)
+                    .type(DIRECT_EXCHANGE)),
                 sender.declareQueue(QueueSpecification.queue(DEAD_LETTER)
                     .durable(DURABLE)
                     .exclusive(!EXCLUSIVE)
@@ -214,6 +217,10 @@ public class 
DistributedDeletedMessageVaultDeletionCallback implements DeleteMes
                 sender.bind(BindingSpecification.binding()
                     .exchange(EXCHANGE)
                     .queue(QUEUE)
+                    .routingKey(EMPTY_ROUTING_KEY)),
+                sender.bind(BindingSpecification.binding()
+                    .exchange(DEAD_LETTER)
+                    .queue(DEAD_LETTER)
                     .routingKey(EMPTY_ROUTING_KEY)))
             .then()
             .block();
@@ -249,8 +256,10 @@ public class 
DistributedDeletedMessageVaultDeletionCallback implements DeleteMes
             return callback.forMessage(copyCommandDTO.asPojo(mailboxIdFactory, 
messageIdFactory, blobIdFactory))
                 .timeout(Duration.ofMinutes(5))
                 .onErrorResume(e -> {
-                    LOGGER.error("Failed executing deletion callback for {}", 
copyCommandDTO.messageId, e);
-                    delivery.nack(REQUEUE);
+                    LOGGER.error("Failed executing deletion callback for {}, 
routing to the dead-letter queue", copyCommandDTO.messageId, e);
+                    // Do not requeue: a failing message (e.g. poisonous 
payload) would otherwise loop forever and block
+                    // the work queue. Dead-letter it instead so it can be 
inspected/replayed manually.
+                    delivery.nack(!REQUEUE);
                     return Mono.empty();
                 })
                 .doOnSuccess(any -> delivery.ack())


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to