dotnet/yarp · error · ArgumentException

A header name is required.

Error message

A header name is required.

What it means

The `HeaderMatcher` constructor validates that a non-empty header name is provided, since a header matcher with no name cannot match anything. This validation runs during config verification when route header match rules are converted from `HeaderMatchConfig` to `HeaderMatcher` instances. The `ArgumentException` identifies the null/empty name as the problem.

Source

Thrown at src/ReverseProxy/Routing/HeaderMatcher.cs:24

using System.Linq;
using Microsoft.Net.Http.Headers;
using Yarp.ReverseProxy.Configuration;

namespace Yarp.ReverseProxy.Routing;

/// <summary>
/// A request header matcher used during routing.
/// </summary>
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;

View on GitHub (pinned to bd11867bee)

Solutions

  1. Inspect the route configuration (appsettings.json, in-memory config, or custom provider output) for header match rules with empty or missing `Header` fields and provide a valid header name.
  2. If config is generated dynamically, add validation at the generation layer to reject or skip header matches with empty names before they reach YARP.
  3. Search for `"Header": ""` or `"Header": null` in the configuration source.
  4. Ensure the header name is a valid HTTP header name (e.g., `X-Custom-Header`, `Authorization`, `Accept`).

Example fix

// before — appsettings.json with empty header name
"Routes": {
  "my-route": {
    "Match": {
      "Path": "/api",
      "Headers": [
        { "Header": "", "Values": ["value1"] } // bug!
      ]
    }
  }
}
// after — provide a valid header name
"Routes": {
  "my-route": {
    "Match": {
      "Path": "/api",
      "Headers": [
        { "Header": "X-Api-Key", "Values": ["secret123"] }
      ]
    }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate header match config before adding to route
static bool IsValidHeaderMatch(HeaderMatchConfig match)
{
    return !string.IsNullOrEmpty(match.Header);
}

Type guard

static bool IsValidHeaderMatcherConfig(string? name, IReadOnlyList<string>? values, string mode)
    => !string.IsNullOrEmpty(name)
    && ((mode is "Exists" or "NotExists") || (values is { Count: > 0 }));

Try / catch

// Not applicable — fix the configuration to provide a valid header name.
// The error surfaces during config validation at startup.

Prevention

When it happens

Trigger: A route in the config defines a header match with an empty or null `Header` field (e.g., `{ "Match": { "Headers": [{ "Header": "", "Values": ["x"] }] } }`). During `VerifyRoutesAsync`, the config validator constructs a `HeaderMatcher` for each header rule, and the constructor throws because `name` is empty.

Common situations: A typo or placeholder in the route configuration leaves the header name empty. A dynamic config generator (e.g., a Kubernetes ingress controller or custom config provider) produces a header match with a null header name due to a missing field in the source data. Configuration was copy-pasted and the header name wasn't updated.

Related errors


AI-assisted analysis of dotnet/yarp@bd11867bee (2026-08-13). Data as JSON: /api/errors/ad75989d2ca2abff. Report an issue: GitHub.