microsoft/aspire · error

Expected IngressProfile to be a…

Error message

Expected IngressProfile to be a Azure.Provisioning.ContainerService.ManagedClusterIngressProfile but found {ipInstance.GetType().FullName}.

What it means

The injector successfully fetched a non-null IngressProfile instance via reflection, but its runtime type's full name does not equal the expected 'Azure.Provisioning.ContainerService.ManagedClusterIngressProfile'. This is a guard against the Azure.Provisioning surface changing shape (renamed/replaced internal type), since the injector then invokes DefineProperty<T> on that instance by reflection.

Solutions

  1. Verify the resolved Azure.Provisioning.ContainerService assembly and version; pin the known-good version (1.0.0-beta.6)
  2. Inspect the actual typeFullName in the message; if the SDK renamed the type, update the IngressProfileTypeFullName constant or replace the injector with the public typed API
  3. If the type is now public, migrate away from reflection entirely (aspire issue 17060)
  4. Check for conflicting Azure.Provisioning.* versions with a NuGet graph audit (dotnet list package --include-transitive)

Example fix

// before
private const string IngressProfileTypeFullName = "Azure.Provisioning.ContainerService.ManagedClusterIngressProfile";
// after (if the SDK renamed the internal type)
private const string IngressProfileTypeFullName = "Azure.Provisioning.ContainerService.ManagedClusterIngressProfileVNext"; // match the new SDK type
Defensive patterns

Strategy: type-guard

Validate before calling

static bool HasExpectedIngressProfile(ContainerServiceManagedCluster aks)
{
    var props = typeof(ContainerServiceManagedCluster).GetProperty("Properties", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(aks);
    var ip = props?.GetType().GetProperty("IngressProfile", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(props);
    return ip?.GetType().FullName == "Azure.Provisioning.ContainerService.ManagedClusterIngressProfile";
}

Type guard

static object? GetIngressProfileOrNull(ContainerServiceManagedCluster aks)
    => typeof(ContainerServiceManagedCluster).GetProperty("Properties", BindingFlags.NonPublic | BindingFlags.Instance) is { } pp
       && pp.GetValue(aks) is { } props
       && props.GetType().GetProperty("IngressProfile", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(props) is { } ip
       && ip.GetType().FullName == "Azure.Provisioning.ContainerService.ManagedClusterIngressProfile"
        ? ip : null;

Try / catch

try
{
    AksPreviewIngressProfileInjector.Inject(aks, gatewayApi: true, applicationLoadBalancer: true);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Expected IngressProfile to be a"))
{
    // Log the actual type from ex.Message and pin or adapt to the new Azure.Provisioning version.
}

Prevention

When it happens

Trigger: Running the injector against an Azure.Provisioning.ContainerService version where ManagedClusterProperties.IngressProfile is typed as a different (renamed, new assembly, or replaced) type than Azure.Provisioning.ContainerService.ManagedClusterIngressProfile, or where assembly-identity differences yield a distinct FullName.

Common situations: Package version drift after upgrading Azure.Provisioning.*; binding a different Azure.Provisioning.ContainerService assembly via transitive dependency resolution; Microsoft regenerating the SDK with a renamed internal type.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/9c73fe8162b4e07f. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.Azure.Kubernetes/AksPreviewIngressProfileInjector.cs:178

        // ContainerServiceManagedCluster.Properties is internal and exposes the
        // ManagedClusterProperties complex object that owns IngressProfile (also internal).
        var clusterPropsProp = typeof(ContainerServiceManagedCluster).GetProperty(
            "Properties",
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
            ?? throw new InvalidOperationException("ContainerServiceManagedCluster.Properties not found via reflection. The Azure.Provisioning surface may have changed; review AksPreviewIngressProfileInjector.");
        var clusterProps = clusterPropsProp.GetValue(aks)
            ?? throw new InvalidOperationException("ContainerServiceManagedCluster.Properties returned null.");

        var ipProp = clusterProps.GetType().GetProperty(
            "IngressProfile",
            BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
            ?? throw new InvalidOperationException("ManagedClusterProperties.IngressProfile not found via reflection. The Azure.Provisioning surface may have changed; review AksPreviewIngressProfileInjector.");
        var ipInstance = ipProp.GetValue(clusterProps)
            ?? throw new InvalidOperationException("ManagedClusterProperties.IngressProfile was null even after assigning IngressWebAppRouting; the Azure.Provisioning lazy-initialization behavior may have changed.");

        if (ipInstance.GetType().FullName != IngressProfileTypeFullName)
        {
            throw new InvalidOperationException($"Expected IngressProfile to be a {IngressProfileTypeFullName} but found {ipInstance.GetType().FullName}.");
        }

        return ipInstance;
    }
}

View on GitHub (pinned to 25830f84bd)