dotnet/yarp · error · InvalidOperationException

IProxyConfigProvider.GetConfig returned a null value.

Error message

IProxyConfigProvider.GetConfig returned a null value.

What it means

When `ProxyConfigManager` calls `IProxyConfigProvider.GetConfig()`, it validates the returned object is not null. A null return is treated as a provider bug — the contract requires a non-null `IProxyConfig` instance. This check runs during both initial load and config reloads, and the exception propagates up through the `InitialLoadAsync` wrapper (error 27).

Source

Thrown at src/ReverseProxy/Management/ProxyConfigManager.cs:332

        ListenForConfigChanges();

        void OnConfigLoadError(ConfigState instance, Exception ex)
        {
            instance.LoadFailed = true;
            Log.ErrorReloadingConfig(_logger, ex);

            foreach (var configChangeListener in _configChangeListeners)
            {
                configChangeListener.ConfigurationLoadingFailed(instance.Provider, ex);
            }
        }
    }

    private static void ValidateConfigProperties(IProxyConfig config)
    {
        if (config is null)
        {
            throw new InvalidOperationException($"{nameof(IProxyConfigProvider.GetConfig)} returned a null value.");
        }

        if (config.ChangeToken is null)
        {
            throw new InvalidOperationException($"{nameof(IProxyConfig.ChangeToken)} has a null value.");
        }
    }

    private ValueTask<IProxyConfig> LoadConfigAsync(IProxyConfigProvider provider, CancellationToken cancellationToken)
    {
        var config = provider.GetConfig();
        ValidateConfigProperties(config);

        if (_destinationResolver.GetType() == typeof(NoOpDestinationResolver))
        {
            return new(config);
        }

View on GitHub (pinned to bd11867bee)

Solutions

  1. In the custom `IProxyConfigProvider.GetConfig()` implementation, ensure every code path returns a non-null `IProxyConfig` — add a fallback that returns an empty config rather than null.
  2. Return an `IProxyConfig` with empty routes and clusters lists if no configuration is available, rather than returning null.
  3. Throw a descriptive exception from `GetConfig()` if config cannot be loaded, so the failure is explicit rather than a null contract violation.
  4. Enable nullable reference types (`<Nullable>enable</Nullable>`) so the compiler flags null-returning paths at build time.
  5. Add a unit test that calls `GetConfig()` and asserts the result is non-null.

Example fix

// before — returns null when no config loaded
public IProxyConfig GetConfig()
{
    if (_loadedConfig is null)
        return null; // bug!
    return _loadedConfig;
}
// after — always returns a valid IProxyConfig
public IProxyConfig GetConfig()
{
    return _loadedConfig ?? new InMemoryConfig(
        routes: Array.Empty<RouteConfig>(),
        clusters: Array.Empty<ClusterConfig>());
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate your provider before registration
public IProxyConfig GetConfig()
{
    var config = BuildConfig();
    if (config is null)
        throw new InvalidOperationException("Failed to build proxy config from source");
    return config;
}

Type guard

static bool IsValidProxyConfig(IProxyConfig? config)
    => config is not null && config.ChangeToken is not null;

Try / catch

// Not applicable — fix the provider to never return null. This is a contract violation.

Prevention

When it happens

Trigger: A custom `IProxyConfigProvider` implementation's `GetConfig()` method returns `null` — typically due to a missing `return` statement, a conditional that doesn't cover all paths, or a logic error where the config object is constructed only under certain conditions.

Common situations: A developer writes a custom config provider and forgets to return the config object in an edge case. A provider dynamically loads config from an external source (e.g., a database or API) and returns null when the source is unavailable instead of throwing or returning an empty config.

Related errors


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