microsoft/aspire · error · InvalidOperationException
Azure sandbox endpoint
Error message
Azure sandbox endpoint '{_endpointReferenceExpression.Endpoint.EndpointName}' on resource '{_resource.TargetResource.Name}' does not have a deployed URL yet. Runtime sandbox URLs cannot be used as first-pass Azure provisioning values; deploy the producing sandbox before resolving this reference. What it means
AzureSandboxEndpointPropertyValueProvider resolves sandbox endpoint URLs, but during first-pass Azure provisioning a runtime sandbox URL does not exist yet. When no known static value is available, the provider throws, explaining that runtime sandbox URLs cannot be used as first-pass provisioning values. The producing sandbox must be deployed before this reference can resolve.
Solutions
- Deploy the producing sandbox first so a deployed URL exists, then re-run the resolution.
- Provide a known static value via configuration so GetKnownValueWithoutDeploymentState() returns it.
- Use the ValueProviderContext overload during provisioning so deployment state can be consulted.
- Add an explicit dependency (WaitFor) on the sandbox resource so evaluation happens after deployment.
Example fix
// before: reading the sandbox URL during first-pass provisioning var url = await provider.GetValueAsync(ct); // throws: no deployed URL yet // after: ensure the consumer depends on the sandbox myResource.WaitFor(sandboxResource); // reference resolves only after deployment produces a URL
Defensive patterns
Strategy: fallback
Validate before calling
// before referencing, check whether a known/static value exists
if (!config.HasKey($"{resourceName}:endpoints:{endpointName}:url"))
{
// schedule the sandbox deployment first instead of resolving now
} Type guard
static bool HasDeployedUrl(AzureSandboxEndpointPropertyValueProvider provider) =>
provider.ValueExpression is { } expr && ConfigContainsKey(expr); // known value check Try / catch
try
{
url = await provider.GetValueAsync(cancellationToken);
}
catch (UnresolvedEndpointException)
{
// fallback: trigger sandbox deployment, then retry resolution
await DeploySandboxAsync(targetResource);
url = await provider.GetValueAsync(cancellationToken);
} Prevention
- Add WaitFor/dependency edges so the producing sandbox deploys before consumers resolve its endpoints.
- Do not evaluate sandbox endpoint references during publish/manifest generation.
- Keep deployment state files present when provisioning incrementally.
- Provide static config overrides when a URL is known outside the deployment pipeline.
When it happens
Trigger: Calling the parameterless-context GetValueAsync(CancellationToken) when GetKnownValueWithoutDeploymentState() returns null; e.g. an endpoint reference to another sandbox resource's endpoint evaluated outside a deployment-state-aware context.
Common situations: Referencing a sandbox resource's endpoint from another resource's config during provision/publish before the sandbox was ever deployed; provisioning with no saved deployment state; wiring consumers to sandbox endpoints at first-pass evaluation.
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
- Endpoint ' ' on resource ' ' uses transport ' '. Azure…
- Endpoint ' ' on resource ' ' is not exposed by the Azure…
- Endpoint ' ' on resource ' ' does not have a target port.
- Endpoint ' ' on resource ' ' is not exposed by the Azure…
- Endpoint ' ' on project resource ' ' is exposed through…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/0eb57e4e5f6d11a9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxEndpointPropertyValueProvider.cs:50
if (endpointReferenceExpression.Property == EndpointProperty.TargetPort)
{
_targetPort = ResolveEndpointTargetPort(resource, endpointReferenceExpression.Endpoint.EndpointName) ??
throw new InvalidOperationException($"Endpoint '{endpointReferenceExpression.Endpoint.EndpointName}' on resource '{resource.TargetResource.Name}' does not have a target port.");
}
else
{
var sandboxEndpoint = ResolveSandboxEndpoint(resource, endpointReferenceExpression.Endpoint);
_sandboxEndpoint = sandboxEndpoint;
_targetPort = sandboxEndpoint.TargetPort;
}
}
public string ValueExpression =>
$"{{{_resource.Name}.endpoints.{_endpointReferenceExpression.Endpoint.EndpointName}.{_endpointReferenceExpression.Property.ToString().ToLowerInvariant()}}}";
public ValueTask<string?> GetValueAsync(CancellationToken cancellationToken = default)
{
return new(GetKnownValueWithoutDeploymentState() ?? throw CreateUnresolvedEndpointException());
}
public async ValueTask<string?> GetValueAsync(ValueProviderContext context, CancellationToken cancellationToken = default)
{
if (GetKnownValueWithoutDeploymentState() is { } knownValue)
{
return knownValue;
}
if (context.ExecutionContext is null)
{
throw CreateUnresolvedEndpointException();
}
var deploymentStateManager = context.ExecutionContext.Services.GetRequiredService<IDeploymentStateManager>();
var stateSection = await deploymentStateManager
.AcquireSectionAsync(AzureSandboxContainerDeployment.GetStateSectionName(_resource), cancellationToken)
.ConfigureAwait(false);View on GitHub (pinned to 25830f84bd)