# Nack All (/sdks/csharp/how-to/queues/nack-all)



## Overview [#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 [#prerequisites]

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

## Code [#code]

```csharp title="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 [#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.

## Related [#related]

* [Pattern overview](/learn/queues/getting-started)
* [C# SDK Reference](/sdks/csharp/reference)
* [Send & Receive](/sdks/csharp/tutorials/send-receive)
* [Ack All](/sdks/csharp/how-to/queues/ack-all)
