microsoft/aspire · error

ContainerServiceManagedCluster.Properties not found via…

Error message

ContainerServiceManagedCluster.Properties not found via reflection. The Azure.Provisioning surface may have changed; review AksPreviewIngressProfileInjector.

What it means

GetIngressProfileInstance reflects over ContainerServiceManagedCluster to fetch its (internal) Properties property, which owns the ingress profile. This error is thrown when GetProperty("Properties", Public|NonPublic|Instance) returns null — the Azure.Provisioning.ContainerService type no longer has a Properties member, so the injector cannot reach the internal ManagedClusterProperties object that owns IngressProfile.

Solutions

  1. Pin Azure.Provisioning.ContainerService to the version Aspire was validated against (1.0.0-beta.6) in Directory.Packages.props
  2. Inspect the installed ContainerServiceManagedCluster type for the new location of the properties complex object and update the GetIngressProfileInstance reflection lookup accordingly
  3. If IngressProfile/GatewayApi/ApplicationLoadBalancer became public in the new version, replace the reflection injector with the typed public-subclass pattern (see ContainerAppEnvironmentDotnetComponentResource for the pattern)
  4. Restore clean packages (nuget locals all -clear) to rule out a stale/mixed assembly set
  5. Track microsoft/aspire#17060 and Azure/azure-sdk-for-net#59225 for the upstream fix that deletes this reflection code

Example fix

// before
var clusterPropsProp = typeof(ContainerServiceManagedCluster).GetProperty("Properties", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
    ?? throw new InvalidOperationException("...Properties not found...");
// after (if upstream flattened properties)
var clusterProps = aks; // properties now live directly on the construct
var ipProp = clusterProps.GetType().GetProperty("IngressProfile", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
    ?? throw new InvalidOperationException("...IngressProfile not found...");
Defensive patterns

Strategy: fallback

Validate before calling

var propsProp = typeof(ContainerServiceManagedCluster).GetProperty("Properties",
    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (propsProp is null)
{
    throw new InvalidOperationException("ContainerServiceManagedCluster.Properties is unavailable in the bound Azure.Provisioning.ContainerService version; preview ingress injection is not supported.");
}

Try / catch

try
{
    AksPreviewIngressProfileInjector.Inject(aks, gatewayApi, applicationLoadBalancer);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Properties not found"))
{
    throw new InvalidOperationException("AKS preview ingress features require a compatible Azure.Provisioning.ContainerService version (1.0.0-beta.6).", ex);
}

Prevention

When it happens

Trigger: A newer Azure.Provisioning.ContainerService package renamed or removed ManagedClusterProperties/Properties on ContainerServiceManagedCluster, and the app model enables AKS preview ingress features (gatewayAPI or applicationLoadBalancer) so AksPreviewIngressProfileInjector.Inject runs during publish/Bicep generation.

Common situations: Upgrading Azure.Provisioning.ContainerService beyond 1.0.0-beta.6 via central package management; a transitive dependency upgrading the package; using an Aspire build against a mismatched azure-sdk-for-net beta where the cluster model was reshaped (e.g. properties flattened into top-level properties).

Related errors


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

Appendix: source

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

                    new[] { "applicationLoadBalancer", "enabled" },
                    /* isOutput */ false,
                    /* isRequired */ false,
                    /* isSecure */ false,
                    /* defaultValue */ null,
                    /* format */ null,
                ])!;
            enabled.Assign(true);
        }
    }

    private static object GetIngressProfileInstance(ContainerServiceManagedCluster aks)
    {
        // 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)