dotnet/yarp · error · ArgumentException

A non-empty CustomMetadata value is required

Error message

A non-empty CustomMetadata value is required

What it means

This is sample code in testassets/ReverseProxy.Code/MyTransformProvider, a custom ITransformProvider that reads a 'CustomMetadata' entry from route/cluster Metadata and stamps it onto the proxied request. Apply throws ArgumentException directly if the entry exists but its value is null or empty, because there is no meaningful header value to write. (The ValidateRoute/ValidateCluster overloads report the same condition via context.Errors instead of throwing.)

Source

Thrown at testassets/ReverseProxy.Code/MyTransformProvider.cs:45

        // Check all clusters for a custom property and validate the associated transform data.
        if (context.Cluster.Metadata?.TryGetValue("CustomMetadata", out var value) ?? false)
        {
            if (string.IsNullOrEmpty(value))
            {
                context.Errors.Add(new ArgumentException("A non-empty CustomMetadata value is required"));
            }
        }
    }

    public void Apply(TransformBuilderContext transformBuildContext)
    {
        // Check all routes for a custom property and add the associated transform.
        if ((transformBuildContext.Route.Metadata?.TryGetValue("CustomMetadata", out var value) ?? false)
            || (transformBuildContext.Cluster?.Metadata?.TryGetValue("CustomMetadata", out value) ?? false))
        {
            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentException("A non-empty CustomMetadata value is required");
            }

            transformBuildContext.AddRequestTransform(transformContext =>
            {
                transformContext.ProxyRequest.Options.Set(new HttpRequestOptionsKey<string>("CustomMetadata"), value);
                return default;
            });
        }
    }
}

View on GitHub (pinned to bd11867bee)

Solutions

  1. Set the CustomMetadata value to a non-empty string in the route/cluster Metadata.
  2. Remove the CustomMetadata key entirely if the transform is not wanted.
  3. If you copied this provider, relax the check or switch to reporting context.Errors in Apply-equivalent validation rather than throwing.

Example fix

// before
"Metadata": { "CustomMetadata": "" }

// after
"Metadata": { "CustomMetadata": "my-value" }
Defensive patterns

Strategy: validation

Validate before calling

// In config loading, strip or reject empty CustomMetadata before the transform runs.
foreach (var route in config.Routes) {
    if (route.Metadata?.TryGetValue("CustomMetadata", out var v) == true
        && string.IsNullOrEmpty(v)) {
        throw new InvalidOperationException($"Route {route.RouteId} has empty CustomMetadata");
    }
}

Prevention

When it happens

Trigger: Configuring a route or cluster with Metadata containing the key "CustomMetadata" mapped to an empty string (or null), then building/running the proxy so Apply executes during transform construction.

Common situations: Copying the sample and leaving CustomMetadata as "" in appsettings; environment-variable substitution that yields empty; JSON like "CustomMetadata": ""; a deployment that sets the metadata key but forgets the value.

Related errors


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