dotnet/yarp · error · Exception
rate: Wait(count={count}) exceeds limiter's burst {burst}
Error message
rate: Wait(count={count}) exceeds limiter's burst {burst} What it means
Thrown by the rate Limiter (a Go-style time/rate port) when WaitAsync is called with a count larger than the limiter's configured burst capacity, and the limit is not Limit.Max (unlimited). This mirrors Go's rate limiter semantics: a single reservation larger than burst can never be satisfied and is rejected immediately rather than blocking forever.
Source
Thrown at src/Kubernetes.Controller/Rate/Limiter.cs:156
/// </summary>
/// <param name="count">The count.</param>
/// <param name="cancellationToken">The cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
/// <exception cref="Exception">rate: Wait(count={count}) exceeds limiter's burst {burst}.</exception>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task WaitAsync(int count, CancellationToken cancellationToken)
{
// https://github.com/golang/time/blob/master/rate/rate.go#L226
int burst = default;
Limit limit = default;
lock (_sync)
{
burst = _burst;
limit = _limit;
}
if (count > burst && limit != Limit.Max)
{
throw new Exception($"rate: Wait(count={count}) exceeds limiter's burst {burst}");
}
// Check if ctx is already cancelled
cancellationToken.ThrowIfCancellationRequested();
// Determine wait limit
var waitLimit = limit.DurationFromTokens(count);
while (true)
{
var now = _timeProvider.GetUtcNow();
var r = ReserveImpl(now, count, waitLimit);
if (r.Ok)
{
var delay = r.DelayFrom(now);
if (delay > TimeSpan.Zero)
{
await Task.Delay(delay, cancellationToken).ConfigureAwait(false);View on GitHub (pinned to bd11867bee)
Solutions
- Reduce the count argument to be within the configured burst capacity.
- Increase the burst parameter when constructing the Limiter (e.g., new Limiter(limit, burst: largerValue)).
- If large batches are expected, use Limit.Max for an uncapped limiter or split the wait into smaller counts.
- Check ReserveN().OK() before waiting to detect the over-burst condition without throwing.
Example fix
// before var limiter = new Limiter(Limit.PerSecond(10), burst: 5); await limiter.WaitAsync(count: 8, ct); // throws // after var limiter = new Limiter(Limit.PerSecond(10), burst: 10); await limiter.WaitAsync(count: 8, ct);
Defensive patterns
Strategy: validation
Validate before calling
if (count > burst && limit != Limit.Max)
{
throw new ArgumentOutOfRangeException(nameof(count), $"count {count} exceeds burst {burst}");
}
await limiter.WaitAsync(count, ct); Type guard
static bool IsWithinBurst(Limiter lim, int count) => count <= lim.Burst;
Try / catch
try { await limiter.WaitAsync(count, ct); }
catch (Exception ex) when (ex.Message.Contains("exceeds limiter's burst"))
{ /* reduce count or increase burst, then retry */ } Prevention
- Pre-check count against burst before calling WaitAsync.
- Use ReserveN().OK() to test feasibility without throwing.
- Scale burst with batch size in configuration.
When it happens
Trigger: Calling limiter.WaitAsync(count, ct) where count exceeds the burst value passed to the Limiter constructor. The check fails fast because no amount of waiting can accumulate enough tokens past the burst ceiling.
Common situations: Passing a batch size larger than the configured burst. Raising a batch count without proportionally raising burst. Default burst too small for the workload's reservation size.
Related errors
- A non-empty CustomTransform value is required
- A non-empty CustomMetadata value is required
- One or more exceptions thrown by ResourceInformerCallback.
- Missing required services. Did you call '.AddKubernetesRever
- This version of YARP is incompatible with the current versio
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/9bc0410d159788e7.
Report an issue: GitHub.