dotnet/yarp · error · NotSupportedException

{string.Join(";", transformValues.Keys)}

Error message

{string.Join(";", transformValues.Keys)}

What it means

Thrown by RequestHeadersTransformFactory.Build when a 'RequestHeaderRouteValue' transform key is present but neither 'Set' nor 'Append' is found. Notably this throws NotSupportedException with only the joined keys (no explanatory text), unlike the sibling RequestHeader branch which gives a descriptive ArgumentException — an internal inconsistency. Validate catches the same condition non-throwing at load time.

Source

Thrown at src/ReverseProxy/Transforms/RequestHeadersTransformFactory.cs:112

            else
            {
                throw new ArgumentException($"Unexpected parameters for RequestHeader: {string.Join(';', transformValues.Keys)}. Expected 'Set' or 'Append'");
            }
        }
        else if (transformValues.TryGetValue(RequestHeaderRouteValueKey, out var headerNameFromRoute))
        {
            TransformHelpers.CheckTooManyParameters(transformValues, expected: 2);
            if (transformValues.TryGetValue(AppendKey, out var routeValueKeyAppend))
            {
                context.AddRequestHeaderRouteValue(headerNameFromRoute, routeValueKeyAppend, append: true);
            }
            else if (transformValues.TryGetValue(SetKey, out var routeValueKeySet))
            {
                context.AddRequestHeaderRouteValue(headerNameFromRoute, routeValueKeySet, append: false);
            }
            else
            {
                throw new NotSupportedException(string.Join(";", transformValues.Keys));
            }
        }
        else if (transformValues.TryGetValue(RequestHeaderRemoveKey, out var removeHeaderName))
        {
            TransformHelpers.CheckTooManyParameters(transformValues, expected: 1);
            context.AddRequestHeaderRemove(removeHeaderName);
        }
        else if (transformValues.TryGetValue(RequestHeadersAllowedKey, out var allowedHeaders))
        {
            TransformHelpers.CheckTooManyParameters(transformValues, expected: 1);
            var headersList = allowedHeaders.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
            context.AddRequestHeadersAllowed(headersList);
        }
        else
        {
            return false;
        }

View on GitHub (pinned to bd11867bee)

Solutions

  1. Add 'Set' or 'Append' with the route-value key, e.g. { "RequestHeaderRouteValue": "X-Hdr", "Set": "userId" }.
  2. Fix typos in the key name (case-sensitive).
  3. Ensure config validation runs at startup.
  4. Validate the dictionary keys in code before calling Build.

Example fix

// before
{ "RequestHeaderRouteValue": "X-Hdr" }
// after
{ "RequestHeaderRouteValue": "X-Hdr", "Set": "userId" }
Defensive patterns

Strategy: validation

Validate before calling

if (transformValues.ContainsKey("RequestHeaderRouteValue")
    && !transformValues.ContainsKey("Set")
    && !transformValues.ContainsKey("Append"))
{
    throw new InvalidOperationException(
        "RequestHeaderRouteValue transform requires 'Set' or 'Append'.");
}

Type guard

static bool IsValidRequestHeaderRouteValueTransform(IReadOnlyDictionary<string, string> t)
    => t.ContainsKey("RequestHeaderRouteValue")
       && (t.ContainsKey("Set") || t.ContainsKey("Append"));

Prevention

When it happens

Trigger: A transform dictionary containing { "RequestHeaderRouteValue": "X-Hdr" } without Set/Append. Reaches Build via direct programmatic construction or when config validation is skipped.

Common situations: Missing Set/Append line in a config-driven route transform; typo'd sibling key; incomplete dynamically-generated transform.

Related errors


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