dotnet/yarp · error · ArgumentException

Unexpected parameters for ResponseTrailer: {string.Join(';',

Error message

Unexpected parameters for ResponseTrailer: {string.Join(';', transformValues.Keys)}. Expected 'Set' or 'Append'

What it means

Thrown by ResponseTransformFactory.Build when a 'ResponseTrailer' transform key is present but neither 'Set' nor 'Append' is among the sibling keys. Uses ArgumentException with a descriptive message listing the keys found. An optional 'When' key may also be present. Validate catches the same condition non-throwing during config loading.

Source

Thrown at src/ReverseProxy/Transforms/ResponseTransformFactory.cs:189

                TransformHelpers.CheckTooManyParameters(transformValues, expected: 3);
                condition = Enum.Parse<ResponseCondition>(whenValue, ignoreCase: true);
            }
            else
            {
                TransformHelpers.CheckTooManyParameters(transformValues, expected: 2);
            }

            if (transformValues.TryGetValue(SetKey, out var setValue))
            {
                context.AddResponseTrailer(responseTrailerName, setValue, append: false, condition);
            }
            else if (transformValues.TryGetValue(AppendKey, out var appendValue))
            {
                context.AddResponseTrailer(responseTrailerName, appendValue, append: true, condition);
            }
            else
            {
                throw new ArgumentException($"Unexpected parameters for ResponseTrailer: {string.Join(';', transformValues.Keys)}. Expected 'Set' or 'Append'");
            }
        }
        else if (transformValues.TryGetValue(ResponseHeaderRemoveKey, out var removeResponseHeaderName))
        {
            var condition = ResponseCondition.Success;
            if (transformValues.TryGetValue(WhenKey, out var whenValue))
            {
                TransformHelpers.CheckTooManyParameters(transformValues, expected: 2);
                condition = Enum.Parse<ResponseCondition>(whenValue, ignoreCase: true);
            }
            else
            {
                TransformHelpers.CheckTooManyParameters(transformValues, expected: 1);
            }

            context.AddResponseHeaderRemove(removeResponseHeaderName, condition);
        }
        else if (transformValues.TryGetValue(ResponseTrailerRemoveKey, out var removeResponseTrailerName))

View on GitHub (pinned to bd11867bee)

Solutions

  1. Add 'Set' or 'Append' to the entry, e.g. { "ResponseTrailer": "X-Grpc", "Set": "v" }.
  2. Correct key-name typos (case-sensitive).
  3. Ensure config validation runs at startup.
  4. Validate the dictionary keys in code before calling Build.

Example fix

// before
{ "ResponseTrailer": "X-Grpc" }
// after
{ "ResponseTrailer": "X-Grpc", "Set": "ok", "When": "Success" }
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Prevention

When it happens

Trigger: A transform dictionary like { "ResponseTrailer": "X-Grpc" } with no Set/Append. Reaches Build when config validation is bypassed or transforms are constructed programmatically.

Common situations: appsettings.json transform missing Set/Append; typo'd sibling key; a config-database-driven route store emitting an incomplete trailer transform.

Related errors


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