{"record":{"id":"27798776ac7002c5","repo":"dotnet/yarp","slug":"headername-cannot-be-null-or-empty-277987","errorCode":null,"errorMessage":"'headerName' cannot be null or empty.","messagePattern":"'headerName' cannot be null or empty\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/ReverseProxy/Transforms/RequestHeaderXForwardedForTransform.cs","lineNumber":25,"sourceCode":"using Microsoft.Extensions.Primitives;\n\nnamespace Yarp.ReverseProxy.Transforms;\n\n/// <summary>\n/// Sets or appends the X-Forwarded-For header with the previous client's IP address.\n/// </summary>\npublic class RequestHeaderXForwardedForTransform : RequestTransform\n{\n    /// <summary>\n    /// Creates a new transform.\n    /// </summary>\n    /// <param name=\"headerName\">The header name.</param>\n    /// <param name=\"action\">Action to applied to the header.</param>\n    public RequestHeaderXForwardedForTransform(string headerName, ForwardedTransformActions action)\n    {\n        if (string.IsNullOrEmpty(headerName))\n        {\n            throw new ArgumentException($\"'{nameof(headerName)}' cannot be null or empty.\", nameof(headerName));\n        }\n\n        HeaderName = headerName;\n        Debug.Assert(action != ForwardedTransformActions.Off);\n        TransformAction = action;\n    }\n\n    internal string HeaderName { get; }\n\n    internal ForwardedTransformActions TransformAction { get; }\n\n    /// <inheritdoc/>\n    public override ValueTask ApplyAsync(RequestTransformContext context)\n    {\n        ArgumentNullException.ThrowIfNull(context);\n\n        string? remoteIp = null;\n        var remoteIpAddress = context.HttpContext.Connection.RemoteIpAddress;","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/dotnet/yarp/blob/bd11867bee7df522e7fd3effb08a9c85fd616908/src/ReverseProxy/Transforms/RequestHeaderXForwardedForTransform.cs#L7-L43","documentation":"RequestHeaderXForwardedForTransform's constructor throws ArgumentException for a null/empty headerName. This transform writes the client remote IP into a forwarded header (commonly X-Forwarded-For), so the target header name is required. A Debug.Assert also verifies the action is not Off.","triggerScenarios":"Constructing `new RequestHeaderXForwardedForTransform(headerName, action)` with headerName null/empty. Typically reached when a custom factory or AddTransform callback supplies an empty header name; the built-in forwarded-header factory supplies the configured name.","commonSituations":"Programmatic AddTransform with an uninitialised header-name variable; a custom config extension that forwards an empty string; refactoring that dropped the header name.","solutions":["Pass a real header name such as \"X-Forwarded-For\".","If building dynamically, default to the conventional name when the variable is empty.","Guard against null/empty before constructing."],"exampleFix":"// before\nnew RequestHeaderXForwardedForTransform(\"\", ForwardedTransformActions.Set);\n// after\nnew RequestHeaderXForwardedForTransform(\"X-Forwarded-For\", ForwardedTransformActions.Set);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(headerName))\n    headerName = \"X-Forwarded-For\"; // or reject\nvar t = new RequestHeaderXForwardedForTransform(headerName, action);","typeGuard":"static bool IsValidHeaderName(string? name)\n    => !string.IsNullOrWhiteSpace(name);","tryCatchPattern":null,"preventionTips":["Use the WithForwardedHeaders / AddXForwardedFor extension methods which supply conventional header names.","Default to standard forwarded header names when the source value is empty.","Validate header names at the call site in custom factory code."],"tags":["yarp","transforms","argument-validation","headers","forwarded"],"backgroundTag":null,"analyzedSha":"bd11867bee7df522e7fd3effb08a9c85fd616908","analyzedAt":"2026-08-13T21:29:49.359Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}