KubeMQ
Client SDKsRustHow-to guidesQueues

Dead Letter Queue

Route failed KubeMQ queue messages to a dead-letter channel via QueuePolicy using the Rust SDK.

Which to use

This page is the task-oriented walkthrough: send a message with DLQ routing configured so it reroutes once retries are exhausted. For the max_receive_count()/max_receive_queue() builder-field reference — defaults and edge cases — see Dead Letter Policy.

Overview

A dead-letter queue (DLQ) gives a poison message somewhere to go instead of looping through consumers forever. When a message keeps failing — a malformed payload, a downstream outage, a handler bug — retrying it forever wastes consumer cycles and blocks everything behind it. A DLQ takes that decision out of your hands: past a set number of failed attempts, the broker diverts the message to a separate channel instead of retrying it again.

Routing runs on two builder methods on QueueMessageBuilder: max_receive_count() and max_receive_queue(). Every failed delivery — a nack, a reject, or an expired visibility window — increments the receive count; past the threshold, the broker reroutes the message to the DLQ instead of redelivering it. The DLQ itself is an ordinary queue, consumed like any other channel.

Gotchas: the DLQ doesn't drain itself — a dedicated consumer must watch it. The count increments on any failed delivery, not just deliberate rejections — a slow consumer that lets the visibility window lapse counts the same as an explicit nack. A typo in the DLQ channel name quietly creates an unrelated channel instead of failing loudly.

Prerequisites

  • KubeMQ server running on localhost:50000
  • Rust SDK installed (cargo add kubemq)

Code

main.rs
use kubemq::prelude::*;
use kubemq::QueueMessageBuilder;

#[tokio::main]
async fn main() -> kubemq::Result<()> {
    let client = KubemqClient::builder()
        .host("localhost")
        .port(50000)
        .build()
        .await?;

    let channel = "rust-queues.dead-letter-queue";

    let msg = QueueMessageBuilder::new()
        .channel(channel)
        .body(b"may-fail-processing".to_vec())
        .max_receive_count(3)
        .max_receive_queue("rust-queues.dead-letter-queue.dlq")
        .build();

    let result = client.send_queue_message(msg).await?;
    println!("Sent with DLQ policy: id={}", result.message_id);

    client.close().await?;
    Ok(())
}

How It Works

  • max_receive_count(3) limits delivery attempts to 3 before routing to the dead-letter queue.
  • max_receive_queue specifies the target channel for failed messages.
  • The server automatically routes messages after the receive count is exceeded.
  • Review timeouts, channel names, and client IDs before running against shared environments.
  • Run the program while the server from the prerequisites is available.

Was this page helpful?

On this page