microsoft/aspire · error · InvalidOperationException

Endpoint ' ' on resource ' ' is not exposed by the Azure…

Error message

Endpoint '{_endpointReferenceExpression.Endpoint.EndpointName}' on resource '{_resource.TargetResource.Name}' is not exposed by the Azure sandbox deployment target.

What it means

Thrown by TryGetUrl when the provider's _sandboxEndpoint is null, i.e. the endpoint being referenced was never exposed/resolved by the Azure sandbox deployment target. Without a resolved sandbox endpoint there is no corresponding deployment-state URL to look up.

Solutions

  1. Configure the producing endpoint as an external HTTP endpoint on the Azure sandbox container (WithHttpEndpoint + external exposure).
  2. Ensure endpoint names match exactly between the producer's declaration and the consumer's EndpointReference.
  3. Re-run the deployment so the deployment state contains the Ports entry for this endpoint.
  4. Verify the resource is actually an AzureSandboxContainerResource whose target exposes the endpoint.

Example fix

// before
.WithEndpoint(name: "http") // not external/HTTP for sandbox
// after
.WithHttpEndpoint(port: 8080, targetPort: 8080, name: "http", isExternal: true);
Defensive patterns

Strategy: validation

Validate before calling

bool IsExposedExternalHttp(IResource r, string endpointName) =>
    r.ResolveEndpoints().Any(e => e.EndpointName == endpointName && e.IsExternal && string.Equals(e.UriScheme, "http", StringComparison.OrdinalIgnoreCase));

Try / catch

try { var url = await provider.GetValueAsync(); }
catch (InvalidOperationException ex) { logger.LogError(ex, "Endpoint not exposed by sandbox target"); throw; }

Prevention

When it happens

Trigger: GetValueAsync → TryGetUrl on a property provider whose endpoint was not registered as an external HTTP endpoint on the sandbox deployment target, so ResolveSandboxEndpoint produced nothing and _sandboxEndpoint stayed null.

Common situations: Referencing an endpoint's URL from a consuming resource while the producing container's endpoint is not marked external/HTTP in the sandbox target; endpoint renamed on the producer but not the consumer.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Azure.Sandboxes/AzureSandboxEndpointPropertyValueProvider.cs:124

            EndpointProperty.Url => url,
            EndpointProperty.Host or EndpointProperty.IPV4Host => uri.Host,
            EndpointProperty.Port => uri.Port.ToString(CultureInfo.InvariantCulture),
            EndpointProperty.TargetPort => _targetPort.ToString(CultureInfo.InvariantCulture),
            EndpointProperty.Scheme => uri.Scheme,
            EndpointProperty.HostAndPort => uri.IsDefaultPort ? uri.Host : uri.Authority,
            EndpointProperty.TlsEnabled => string.Equals(uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase) ? bool.TrueString : bool.FalseString,
            _ => throw new InvalidOperationException($"The property '{_endpointReferenceExpression.Property}' is not supported for the endpoint '{_endpointReferenceExpression.Endpoint.EndpointName}'.")
        };
    }

    private InvalidOperationException CreateUnresolvedEndpointException() =>
        new($"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.");

    private bool TryGetUrl(DeploymentStateSection stateSection, [NotNullWhen(true)] out string? url)
    {
        url = null;
        var sandboxEndpoint = _sandboxEndpoint ??
            throw new InvalidOperationException($"Endpoint '{_endpointReferenceExpression.Endpoint.EndpointName}' on resource '{_resource.TargetResource.Name}' is not exposed by the Azure sandbox deployment target.");

        // Sandbox deployment state stores exposed ADC ports as:
        //   { "Ports": [{ "Name": "http", "Port": 8080, "Url": "https://<sandbox-id>--8080.<region>.adcproxy.io/" }] }
        // Multiple Aspire endpoints can share the same target port, so fall back to target-port
        // matching when the persisted representative name differs from the requested endpoint name.
        if (stateSection.Data["Ports"] is not JsonArray ports)
        {
            return false;
        }

        JsonObject? fallbackPort = null;
        foreach (var port in ports.OfType<JsonObject>())
        {
            if (port["Port"]?.GetValue<int>() == sandboxEndpoint.TargetPort)
            {
                fallbackPort ??= port;
            }

View on GitHub (pinned to 25830f84bd)