microsoft/aspire · error · DistributedApplicationException

Couldn't find required instance ID for index

Error message

Couldn't find required instance ID for index {instanceIndex} on resource {resource.Name}.

What it means

DcpExecutor looks up a specific replicated instance of a resource by its replica index (e.g. instance 0, 1, 2 of a scaled resource) and none of the resource's DCP replicas has that index. Aspire throws DistributedApplicationException because code downstream requires an instance at exactly that index to proceed. This is an internal consistency failure: the resource model said there should be N instances but DCP state disagrees.

Solutions

  1. Retry the operation after a short delay so DCP can finish creating the replica at that index.
  2. Verify replica count settings on the resource (WithReplicas) match what you expect before restarting a specific instance.
  3. Check DCP state (dcp CLI / ~/.aspine dcp logs) for missing or failed replicas.
  4. Restart the AppHost to rebuild a consistent DCP state if the instance list appears stale.

Example fix

// before: restart a replica index without checking instance count
await executor.StopResourceAsync(reference, ct);
// after: guard against missing instances by enumerating instances first
var instances = await GetInstancesAsync(resource, ct);
if (instances.Any(i => i.Index == instanceIndex))
{
    await RestartInstanceAsync(resource, instanceIndex, ct);
}
Defensive patterns

Strategy: retry

Validate before calling

var instances = await GetInstancesAsync(resource, ct);
if (!instances.Any(i => i.Index == instanceIndex))
{
    // instance not ready; defer or recompute instead of proceeding
}

Type guard

static bool HasInstance(IEnumerable<IAppResource> instances, int index) => instances.Any(i => i.Index == index);

Try / catch

try { var instance = GetInstanceByIndex(resource, index); }
catch (DistributedApplicationException ex) when (ex.Message.Contains("Couldn't find required instance ID"))
{
    // log, wait for DCP reconciliation, retry
}

Prevention

When it happens

Trigger: Calling DcpExecutor APIs such as GetInstanceAsync/instance lookup (used internally during endpoint allocation and restart flows) with an instanceIndex for which no replica currently exists on the resource — e.g. during scale-down races, restarts of specific replicas, or when DCP has not yet created/has already deleted that replica.

Common situations: Restarting a specific replica while DCP is recreating instances; race between app-model replica count changes and DCP watch events; corrupt/stale DCP state where the instance list is out of sync; bugs in replica index computation during endpoint assignment.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting/Dcp/DcpExecutor.cs:1145

    /// <summary>
    /// Gets information about the resource's DCP instance. ReplicaInstancesAnnotation is added in BeforeStartEvent.
    /// </summary>
    internal static DcpInstance GetDcpInstance(IResource resource, int instanceIndex)
    {
        if (!resource.TryGetInstances(out var instances))
        {
            throw new DistributedApplicationException($"Couldn't find required {nameof(DcpInstancesAnnotation)} annotation on resource {resource.Name}.");
        }

        foreach (var instance in instances)
        {
            if (instance.Index == instanceIndex)
            {
                return instance;
            }
        }

        throw new DistributedApplicationException($"Couldn't find required instance ID for index {instanceIndex} on resource {resource.Name}.");
    }

    /// <summary>
    /// Create a patch update using the specified resource.
    /// A copy is taken of the resource to avoid permanently changing it.
    /// </summary>
    private static V1Patch CreatePatch<T>(T obj, Action<T> change) where T : CustomResource
    {
        // This method isn't very efficient.
        // If mass or frequent patches are required then we may want to create patches manually.
        var current = JsonSerializer.SerializeToNode(obj);

        var copy = JsonSerializer.Deserialize<T>(current)!;
        change(copy);

        var changed = JsonSerializer.SerializeToNode(copy);

        var jsonPatch = JsonPatch.Create(current, changed);

View on GitHub (pinned to 25830f84bd)