App-vNext/Polly · error · ValidationException
{PrimaryMessage}\nValidation Errors:\n{error.ErrorMessage}
Error message
{PrimaryMessage}\nValidation Errors:\n{error.ErrorMessage} What it means
ValidationHelper.ValidateObject runs data-annotations validation on an options object and, on failure, throws a ValidationException whose message is the primary message followed by each ValidationResult.ErrorMessage on its own line. This is the single funnel through which all Polly.Core strategy options are validated at Add*/Build time, so the thrown message is always '{primary}\nValidation Errors:\n{each error}'.
Source
Thrown at src/Polly.Core/Utils/ValidationHelper.cs:51
var errors = new List<ValidationResult>();
lock (ValidatorLock)
{
valid = Validator.TryValidateObject(context.Instance, new(context.Instance), errors, true);
}
if (!valid)
{
var stringBuilder = new StringBuilder(context.PrimaryMessage);
stringBuilder.AppendLine();
stringBuilder.AppendLine("Validation Errors:");
foreach (var error in errors)
{
stringBuilder.AppendLine(error.ErrorMessage);
}
throw new ValidationException(stringBuilder.ToString());
}
}
}
View on GitHub (pinned to d0e46bdb1e)
Solutions
- Read each ErrorMessage line in the thrown ValidationException; it names the property and the constraint that failed.
- Correct the offending option value to satisfy the annotation (range, required, regex) and rebuild.
- Validate options eagerly after configuration binding using the same data-annotations validator, or configure via the DI options-validation pattern.
Example fix
// before
new RetryStrategyOptions { MaxRetryAttempts = -1, Delay = TimeSpan.FromSeconds(-5) };
// after
new RetryStrategyOptions { MaxRetryAttempts = 3, Delay = TimeSpan.FromSeconds(2) }; Defensive patterns
Strategy: validation
Validate before calling
// Validate options eagerly before adding/building:
var ctx = new ValidationContext(options);
var results = new List<ValidationResult>();
if (!Validator.TryValidateObject(options, ctx, results, true)) {
throw new ValidationException(string.Join("\n", results.Select(r => r.ErrorMessage)));
} Try / catch
try { builder.AddRetry(retryOptions); }
catch (ValidationException ex) {
// ex.Message lists each failing property+constraint; fix and retry
} Prevention
- Read every 'Validation Errors:' line; each names the property and the rule it broke.
- Validate configuration-bound options at startup using data-annotations or the DI options-validation pattern.
- Keep numeric/TimeSpan options inside their documented ranges.
When it happens
Trigger: Configuring any strategy options object with values that violate [Range]/[Required]/[RegularExpression] data annotations (e.g. RetryStrategyOptions.MaxRetryAttempts = -1, TimeoutStrategyOptions.Timeout = negative), then adding the strategy or building the pipeline.
Common situations: Configuration values bound from appsettings without validation; arithmetic that produces out-of-range numbers; copy-pasted options where a field was left at an invalid default; upgrading Polly and hitting newly-added constraints.
Related errors
- No predicates were configured. There must be at least one pr
- This instance of 'CircuitBreakerStateProvider' is already in
- Unable to find a resilience pipeline associated with the key
- Unable to find a generic resilience pipeline of '{typeof(TRe
- numberOfExecutions per timespan must be an integer greater t
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/7df528c1b3d0a56a.
Report an issue: GitHub.