dotnet/yarp · error · ArgumentException
Header values must not be specified when using '{mode}'.
Error message
Header values must not be specified when using '{mode}'. What it means
Thrown by the HeaderMatcher constructor when a header match Mode of Exists or NotExists is selected but one or more match Values are also supplied. Exists/NotExists only test header presence, so supplying values is contradictory. The argument exception targets the `values` parameter so the caller knows which input is at fault.
Source
Thrown at src/ReverseProxy/Routing/HeaderMatcher.cs:33
internal sealed class HeaderMatcher
{
/// <summary>
/// Creates a new instance.
/// </summary>
public HeaderMatcher(string name, IReadOnlyList<string>? values, HeaderMatchMode mode, bool isCaseSensitive)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentException("A header name is required.", nameof(name));
}
if ((mode != HeaderMatchMode.Exists && mode != HeaderMatchMode.NotExists)
&& (values is null || values.Count == 0))
{
throw new ArgumentException("Header values must have at least one value.", nameof(values));
}
if ((mode == HeaderMatchMode.Exists || mode == HeaderMatchMode.NotExists) && values?.Count > 0)
{
throw new ArgumentException($"Header values must not be specified when using '{mode}'.", nameof(values));
}
if (values is not null && values.Any(string.IsNullOrEmpty))
{
throw new ArgumentNullException(nameof(values), "Header values must be not be empty.");
}
Name = name;
Values = values?.ToArray() ?? Array.Empty<string>();
Mode = mode;
Comparison = isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
Separator = name.Equals(HeaderNames.Cookie, StringComparison.OrdinalIgnoreCase) ? ';' : ',';
}
/// <summary>
/// Name of the header to look for.
/// </summary>
public string Name { get; }
View on GitHub (pinned to bd11867bee)
Solutions
- If you only need presence checks, remove all `values` entries for that header matcher (set Mode to Exists/NotExists and omit Values).
- If you actually want to match a header value, change Mode to ExactHeader, HeaderPrefix, ExactHeaderPrefix, or Contains and keep the values.
- Validate the HeaderMatcher config object before construction: for Exists/NotExists modes assert values is null or empty.
Example fix
// before
new HeaderMatcher("X-Flag", new[] { "1" }, HeaderMatchMode.Exists, isCaseSensitive: true);
// after
new HeaderMatcher("X-Flag", values: null, HeaderMatchMode.Exists, isCaseSensitive: true); Defensive patterns
Strategy: validation
Validate before calling
if ((mode == HeaderMatchMode.Exists || mode == HeaderMatchMode.NotExists) && values?.Count > 0)
throw new InvalidOperationException("Exists/NotExists modes cannot take values."); Type guard
static bool IsValidHeaderMatcherConfig(HeaderMatchMode mode, IReadOnlyList<string>? values) =>
(mode == HeaderMatchMode.Exists || mode == HeaderMatchMode.NotExists)
? values is null || values.Count == 0
: values is not null && values.Count > 0; Prevention
- Centralize HeaderMatcher construction behind a factory that enforces mode/values compatibility.
- Validate route config at startup via IValidateOptions so contradictory header rules fail fast.
- In config, treat Exists/NotExists as mutually exclusive with values.
When it happens
Trigger: Constructing `new HeaderMatcher(name, values, HeaderMatchMode.Exists, ...)` or `HeaderMatchMode.NotExists` with a non-empty `values` list. Also reached indirectly when YARP config binds a route's Header values while Mode is set to Exists/NotExists.
Common situations: Copied config from an ExactHeader/PrefixHeader rule and left the `values` array populated after switching Mode to `Exists`. YAML/JSON config that sets both `values` and `mode: HeaderPrefix`->`Exists`. Migration from an older config schema that inferred mode.
Related errors
- Header values must be not be empty.
- Query parameter values must have at least one value.
- Query parameter values must not be specified when using '{na
- Query parameter values must not be empty.
- '{nameof(routeValueKey)}' cannot be null or empty.
AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13).
Data as JSON: /api/errors/5cde4a896ee1c0c5.
Report an issue: GitHub.