KubeMQ
Client SDKsC#How-to guidesQueues

Nack All

Negative-acknowledge all received KubeMQ queue messages at once using the C# SDK to trigger redelivery.

Overview

Bulk nack rejects an entire polled batch of queue messages in a single call instead of settling each one individually. It's the operation you reach for when a failure affects the whole batch at once — a downstream dependency is down, a shared resource lock couldn't be acquired, or a transient error means none of the messages can be processed right now — and retrying them one-by-one would just be extra round-trips for the same outcome.

It works with manual-ack polling: receiver.PollAsync with AutoAck = false locks the returned batch for this receiver during the visibility window, and batch.NackAllAsync() sends one negative-acknowledge that settles every message in the batch, returning them all to the queue for redelivery.

Gotchas: each nacked message increments its receive count, so an unbounded retry loop is one bad NackAllAsync() away — pair it with MaxReceiveCount and a dead-letter policy. NackAllAsync() is all-or-nothing: you can't use it to keep a few messages and reject the rest — that needs per-message ack/nack or a range operation. And calling it on an empty batch is a wasted round-trip, so guard on batch.HasMessages first.

Prerequisites

  • KubeMQ server running on localhost:50000
  • C# SDK installed (dotnet add package KubeMQ.SDK.CSharp)

Code

Program.cs
// KubeMQ .NET SDK — QueuesStream: NackAll via Batch
//
// This example demonstrates receiving messages via the downstream receiver API
// and negatively acknowledging all messages using batch.NackAllAsync().
// NACKed messages are returned to the queue for redelivery.
//
// Prerequisites:
//   - KubeMQ server running on localhost:50000
//   - Send some messages to "csharp-queues.nack-all" first
//   - dotnet run

using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Queues;

await using var client = new KubeMQClient(new KubeMQClientOptions
{
    ClientId = "csharp-queues-nack-all-client",
});
await client.ConnectAsync();

Console.WriteLine("Connected to KubeMQ server");

await using var receiver = await client.CreateQueueDownstreamReceiverAsync();

var batch = await receiver.PollAsync(new QueuePollRequest
{
    Channel = "csharp-queues.nack-all",
    MaxMessages = 10,
    WaitTimeoutSeconds = 5,
    AutoAck = false,
});

Console.WriteLine($"Received {batch.Messages.Count} messages");

if (batch.HasMessages)
{
    await batch.NackAllAsync();
    Console.WriteLine("All messages negatively acknowledged (returned to queue).");
}

Console.WriteLine("Done.");

How It Works

  • PollAsync with AutoAck = false locks the batch for this receiver during the visibility window. No other consumer can see these messages until they are settled or the timeout expires.
  • batch.NackAllAsync() negatively acknowledges every message in the batch in one call, returning them all to the queue immediately for redelivery.
  • This is useful for bulk rollback: if a batch of messages cannot be processed (e.g., a dependency is down), nack all of them and let the queue redistribute to healthy consumers.
  • Each nacked message increments its receive count — pair with MaxReceiveCount to route persistently failing messages to a dead-letter queue.

Was this page helpful?

On this page