dotnet/yarp · error · AggregateException
One or more exceptions thrown by ResourceInformerCallback.
Error message
One or more exceptions thrown by ResourceInformerCallback.
What it means
Thrown as an AggregateException by ResourceInformer after it has dispatched resource events to all registered ResourceInformerCallback delegates. If one or more callbacks throw, each exception is collected and re-thrown as a single aggregate so no callback failure is silently swallowed. This is part of the Kubernetes controller informer loop that watches cluster resources.
Source
Thrown at src/Kubernetes.Controller/Client/ResourceInformer.cs:426
{
List<Exception> innerExceptions = default;
foreach (var registration in _registrations)
{
try
{
registration.Callback.Invoke(eventType, resource);
}
catch (Exception innerException)
{
innerExceptions ??= new List<Exception>();
innerExceptions.Add(innerException);
}
}
if (innerExceptions is not null)
{
throw new AggregateException("One or more exceptions thrown by ResourceInformerCallback.", innerExceptions);
}
}
internal class Registration : IResourceInformerRegistration
{
private bool _disposedValue;
public Registration(ResourceInformer<TResource, TListResource> resourceInformer, ResourceInformerCallback<TResource> callback)
{
ResourceInformer = resourceInformer;
Callback = callback;
lock (resourceInformer._sync)
{
resourceInformer._registrations = resourceInformer._registrations.Add(this);
}
}
~Registration()View on GitHub (pinned to bd11867bee)
Solutions
- Inspect the AggregateException.InnerExceptions to find the root cause from the failing callback.
- Wrap the callback body in try/catch to handle expected failures locally instead of letting them propagate.
- Fix the bug in the callback implementation identified by the inner exception.
- Add logging inside the callback to capture per-event context before failure.
Example fix
// before — callback throws
informer.Register((eventType, resource) =>
{
var name = resource.Metadata.Name; // NullReferenceException if Metadata null
});
// after — guard inside callback
informer.Register((eventType, resource) =>
{
try
{
var name = resource.Metadata?.Name ?? "unknown";
// process
}
catch (Exception ex)
{
_logger.LogError(ex, "Callback failed for {EventType}", eventType);
}
}); Defensive patterns
Strategy: try-catch
Validate before calling
// n/a — cannot validate callback behavior statically; guard at registration time if (callback is null) throw new ArgumentNullException(nameof(callback));
Type guard
// n/a
Try / catch
try { await informerLoopAsync; }
catch (AggregateException ax)
{
foreach (var inner in ax.InnerExceptions)
logger.LogError(inner, "Informer callback failed");
// decide: continue, restart informer, or terminate
} Prevention
- Never let exceptions escape a ResourceInformerCallback — wrap the body in try/catch.
- Log per-event context inside callbacks for diagnosis.
- Keep callbacks fast and side-effect-free; offload heavy work to a queue.
When it happens
Trigger: One or more IResourceInformerRegistration callbacks throw an exception during event dispatch (WatchAdd/WatchModify/WatchDelete). The informer collects all such exceptions across registered callbacks for a given event dispatch cycle and throws the aggregate.
Common situations: A callback has an unhandled bug (null deref, invalid cast on the resource object). A callback calls an external API that fails. Callback logic assumes a resource shape that changed across Kubernetes API versions.
Related errors
- Missing required services. Did you call '.AddKubernetesRever
- rate: Wait(count={count}) exceeds limiter's burst {burst}
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/474e6efd7a137194.
Report an issue: GitHub.