microsoft/aspire · error · InvalidOperationException
MCP server configuration
Error message
MCP server configuration '{builder.Resource.Name}' configures access policies and cannot be marked as existing. What it means
AsExisting rejects MCP server configurations that already carry access policies. Access policies are child resources Aspire would create; on an existing (read-only) reference they cannot be deployed, so the conversion is refused to keep the model consistent.
Solutions
- Remove all WithAccessPolicy calls before calling AsExisting.
- Manage access policies on the existing MCP server configuration outside Aspire (portal/CLI/Bicep).
- Split into two resources: an unconfigured builder marked AsExisting, and drop the modeled policies.
Example fix
// before
var mcp = ns.AddMcpServerConfig("tools", options)
.WithAccessPolicy("api", policyOptions);
mcp.AsExisting(); // throws
// after
var mcp = ns.AddMcpServerConfig("tools", options); // no access policies
mcp.AsExisting(); // grant policies out-of-band instead Defensive patterns
Strategy: validation
Validate before calling
if (mcp.Resource.AccessPolicies.Count == 0)
{
mcp.AsExisting();
} Try / catch
try
{
mcp.AsExisting();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("configures access policies"))
{
// remove WithAccessPolicy calls and grant policies out-of-band
} Prevention
- Never mix access-policy modeling with existing-mode references.
- For existing configs, assign access policies in Azure (portal/CLI/Bicep).
- Check AccessPolicies.Count before converting to existing mode.
When it happens
Trigger: Calling builder.AsExisting() after WithAccessPolicy calls have populated Resource.AccessPolicies on the MCP server configuration.
Common situations: A config modeled with identity access policies that is later pointed at pre-provisioned infrastructure via AsExisting without removing the policy calls.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Existing MCP server configuration
- Access policy resource
- An access policy for principal
- Existing connector connection
- Existing MCP server configuration
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/a7e8508343f021c4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.ConnectorNamespace/AzureConnectorNamespaceExtensions.cs:513
public static IResourceBuilder<AzureConnectorNamespaceMcpServerConfigResource> AsExisting(
this IResourceBuilder<AzureConnectorNamespaceMcpServerConfigResource> builder)
{
ArgumentNullException.ThrowIfNull(builder);
if (builder.Resource.Connectors.Count > 0)
{
throw new InvalidOperationException(
$"MCP server configuration '{builder.Resource.Name}' has connector routes and cannot be marked as existing.");
}
if (!string.IsNullOrWhiteSpace(builder.Resource.Description))
{
throw new InvalidOperationException(
$"MCP server configuration '{builder.Resource.Name}' configures a description and cannot be marked as existing.");
}
if (builder.Resource.AccessPolicies.Count > 0)
{
throw new InvalidOperationException(
$"MCP server configuration '{builder.Resource.Name}' configures access policies and cannot be marked as existing.");
}
builder.Resource.IsExisting = true;
return builder;
}
/// <summary>
/// Adds a Microsoft Entra user or group access policy to a managed MCP server configuration.
/// </summary>
/// <param name="builder">The MCP server configuration resource builder.</param>
/// <param name="name">The Aspire resource name for the policy.</param>
/// <param name="options">The authorized user or group.</param>
/// <returns>The MCP server configuration resource builder.</returns>
/// <remarks>
/// Managed MCP endpoints reject callers that do not have a config-scoped access policy.
/// Connector Namespace currently supports Microsoft Entra users and groups for these policies.
/// The Azure child resource name is set to the principal object ID as required by the service.View on GitHub (pinned to 25830f84bd)