{"record":{"id":"5cde4a896ee1c0c5","repo":"dotnet/yarp","slug":"header-values-must-not-be-specified-when-using-m","errorCode":null,"errorMessage":"Header values must not be specified when using '{mode}'.","messagePattern":"Header values must not be specified when using '(.+?)'\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ReverseProxy/Routing/HeaderMatcher.cs","lineNumber":33,"sourceCode":"internal sealed class HeaderMatcher\n{\n    /// <summary>\n    /// Creates a new instance.\n    /// </summary>\n    public HeaderMatcher(string name, IReadOnlyList<string>? values, HeaderMatchMode mode, bool isCaseSensitive)\n    {\n        if (string.IsNullOrEmpty(name))\n        {\n            throw new ArgumentException(\"A header name is required.\", nameof(name));\n        }\n        if ((mode != HeaderMatchMode.Exists && mode != HeaderMatchMode.NotExists)\n            && (values is null || values.Count == 0))\n        {\n            throw new ArgumentException(\"Header values must have at least one value.\", nameof(values));\n        }\n        if ((mode == HeaderMatchMode.Exists || mode == HeaderMatchMode.NotExists) && values?.Count > 0)\n        {\n            throw new ArgumentException($\"Header values must not be specified when using '{mode}'.\", nameof(values));\n        }\n        if (values is not null && values.Any(string.IsNullOrEmpty))\n        {\n            throw new ArgumentNullException(nameof(values), \"Header values must be not be empty.\");\n        }\n\n        Name = name;\n        Values = values?.ToArray() ?? Array.Empty<string>();\n        Mode = mode;\n        Comparison = isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;\n        Separator = name.Equals(HeaderNames.Cookie, StringComparison.OrdinalIgnoreCase) ? ';' : ',';\n    }\n\n    /// <summary>\n    /// Name of the header to look for.\n    /// </summary>\n    public string Name { get; }\n","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Routing/HeaderMatcher.cs#L15-L51","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nnew HeaderMatcher(\"X-Flag\", new[] { \"1\" }, HeaderMatchMode.Exists, isCaseSensitive: true);\n// after\nnew HeaderMatcher(\"X-Flag\", values: null, HeaderMatchMode.Exists, isCaseSensitive: true);","handlingStrategy":"validation","validationCode":"if ((mode == HeaderMatchMode.Exists || mode == HeaderMatchMode.NotExists) && values?.Count > 0)\n    throw new InvalidOperationException(\"Exists/NotExists modes cannot take values.\");","typeGuard":"static bool IsValidHeaderMatcherConfig(HeaderMatchMode mode, IReadOnlyList<string>? values) =>\n    (mode == HeaderMatchMode.Exists || mode == HeaderMatchMode.NotExists)\n        ? values is null || values.Count == 0\n        : values is not null && values.Count > 0;","tryCatchPattern":null,"preventionTips":["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."],"tags":["routing","header-match","argument-validation","yarp"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}