{"record":{"id":"9584f45c4e7ce72d","repo":"dotnet/yarp","slug":"unexpected-parameters-for-requestheader-string-j","errorCode":null,"errorMessage":"Unexpected parameters for RequestHeader: {string.Join(';', transformValues.Keys)}. Expected 'Set' or 'Append'","messagePattern":"Unexpected parameters for RequestHeader: (.+?)\\. Expected 'Set' or 'Append'","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ReverseProxy/Transforms/RequestHeadersTransformFactory.cs","lineNumber":96,"sourceCode":"        else if (transformValues.TryGetValue(RequestHeaderOriginalHostKey, out var originalHost))\n        {\n            TransformHelpers.CheckTooManyParameters(transformValues, expected: 1);\n            context.AddOriginalHost(bool.Parse(originalHost));\n        }\n        else if (transformValues.TryGetValue(RequestHeaderKey, out var headerName))\n        {\n            TransformHelpers.CheckTooManyParameters(transformValues, expected: 2);\n            if (transformValues.TryGetValue(SetKey, out var setValue))\n            {\n                context.AddRequestHeader(headerName, setValue, append: false);\n            }\n            else if (transformValues.TryGetValue(AppendKey, out var appendValue))\n            {\n                context.AddRequestHeader(headerName, appendValue, append: true);\n            }\n            else\n            {\n                throw new ArgumentException($\"Unexpected parameters for RequestHeader: {string.Join(';', transformValues.Keys)}. Expected 'Set' or 'Append'\");\n            }\n        }\n        else if (transformValues.TryGetValue(RequestHeaderRouteValueKey, out var headerNameFromRoute))\n        {\n            TransformHelpers.CheckTooManyParameters(transformValues, expected: 2);\n            if (transformValues.TryGetValue(AppendKey, out var routeValueKeyAppend))\n            {\n                context.AddRequestHeaderRouteValue(headerNameFromRoute, routeValueKeyAppend, append: true);\n            }\n            else if (transformValues.TryGetValue(SetKey, out var routeValueKeySet))\n            {\n                context.AddRequestHeaderRouteValue(headerNameFromRoute, routeValueKeySet, append: false);\n            }\n            else\n            {\n                throw new NotSupportedException(string.Join(\";\", transformValues.Keys));\n            }\n        }","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Transforms/RequestHeadersTransformFactory.cs#L78-L114","documentation":"Thrown by RequestHeadersTransformFactory.Build when a 'RequestHeader' transform key is present but neither 'Set' nor 'Append' is found among the sibling keys. Unlike the QueryTransformFactory equivalents (which throw NotSupportedException), this uses ArgumentException with a descriptive message naming the keys found. The Validate method reports the same condition non-throwing at config load time.","triggerScenarios":"A transform dictionary like { \"RequestHeader\": \"X-Foo\" } with no Set/Append. Reaches Build when config validation is bypassed/skipped or transforms are built programmatically via ITransformFactory.Build.","commonSituations":"appsettings.json transform object missing the Set/Append line; typo such as 'set' (lowercase); a config-database-driven route store emitting an incomplete transform.","solutions":["Add 'Set' or 'Append' to the transform entry, e.g. { \"RequestHeader\": \"X-Foo\", \"Set\": \"bar\" }.","Correct key-name typos — keys are case-sensitive ('Set', not 'set').","Keep startup config validation enabled so this is caught at startup, not at Build time.","When building in code, assert the dictionary contains Set or Append before calling Build."],"exampleFix":"// before\n{ \"Transforms\": [ { \"RequestHeader\": \"X-Foo\" } ] }\n// after\n{ \"Transforms\": [ { \"RequestHeader\": \"X-Foo\", \"Append\": \"svc\" } ] }","handlingStrategy":"validation","validationCode":"if (transformValues.ContainsKey(\"RequestHeader\")\n    && !transformValues.ContainsKey(\"Set\")\n    && !transformValues.ContainsKey(\"Append\"))\n{\n    throw new InvalidOperationException(\n        \"RequestHeader transform requires 'Set' or 'Append'.\");\n}","typeGuard":"static bool IsValidRequestHeaderTransform(IReadOnlyDictionary<string, string> t)\n    => t.ContainsKey(\"RequestHeader\")\n       && (t.ContainsKey(\"Set\") || t.ContainsKey(\"Append\"));","tryCatchPattern":null,"preventionTips":["Keep YARP startup config validation enabled.","When building transforms in code, assert the required sibling keys are present.","Use a config schema/validator for any non-appsettings transform source."],"tags":["yarp","config","transforms","headers"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}