microsoft/aspire · error · InvalidOperationException
The endpoint ' ' for container resource ' ' must specify…
Error message
The endpoint '{endpoint.Name}' for container resource '{modelResourceName}' must specify the TargetPort value What it means
When mapping Aspire model endpoints to DCP service annotations, DcpModelUtilities validates that every endpoint on a container resource has a concrete TargetPort. Containers do not get a dynamically assigned port inside the container, so a container endpoint without TargetPort has nothing to bind to, and Aspire throws InvalidOperationException at validation time.
Solutions
- Pass targetPort to WithEndpoint/WithHttpEndpoint on the container resource.
- Remember the distinction: for containers, targetPort = the port the app listens on inside the container.
- Set the environment variable (e.g. ASPNETCORE_HTTP_PORTS) in the container to match the targetPort.
- Use a typed endpoint helper (WithHttpEndpoint(port: ...)) that forces the port argument.
Example fix
// before
var cache = builder.AddContainer("cache", "redis", "latest")
.WithHttpEndpoint();
// after
var cache = builder.AddContainer("cache", "redis", "latest")
.WithHttpEndpoint(port: 6379, targetPort: 6379); Defensive patterns
Strategy: validation
Validate before calling
static void EnsureContainerEndpointHasTargetPort(IResource resource, EndpointAnnotation e)
{
if (resource.IsContainer() && EndpointAnnotation.NormalizePort(e.TargetPort) is null)
throw new InvalidOperationException($"Endpoint '{e.Name}' on container '{resource.Name}' needs a TargetPort.");
} Type guard
static bool HasTargetPort(EndpointAnnotation e) => EndpointAnnotation.NormalizePort(e.TargetPort) is not null;
Try / catch
try { await builder.Build().RunAsync(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("must specify the TargetPort"))
{
// fix the endpoint registration on the named container resource
} Prevention
- Always pass targetPort when adding endpoints to container resources
- Set the container's listen-port env var to match targetPort
- Treat project endpoints and container endpoints as different rules
When it happens
Trigger: Calling WithEndpoint/WithHttpEndpoint/WithHttpsEndpoint (or WithEndpoint<T>) on a container resource without supplying targetPort, e.g. builder.AddContainer("x","img").WithHttpEndpoint() with no port argument, then running/publishing the AppHost.
Common situations: Copying project-style endpoint code (where targetPort is optional) onto containers; refactoring a project resource into a container and forgetting to add the container-side port; forgetting that for containers the 'port' is the in-container listening port.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- The endpoint ' ' for resource ' ' is not using a proxy, and…
- At least one gateway endpoint (HTTP or HTTPS) must be…
- AzureSandboxOptions.AutoDeleteEnabled must be set when…
- AzureSandboxOptions.AutoSuspendEnabled must be set when…
- Both SourcePath and Contents are set for a file entry
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/65f2280d25ce82c0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/Dcp/DcpModelUtilities.cs:39
internal static bool ShouldDeferCreateForExplicitStart(IResource modelResource, bool? start)
{
// Explicit-start, non-persistent resources use manual snapshots for dashboard visibility.
// Do not create corresponding DCP objects until the manual start path flips Spec.Start=true; creation
// evaluates callbacks that can prompt for input or depend on start-time state.
return start == false &&
modelResource.TryGetLastAnnotation<ExplicitStartupAnnotation>(out _) &&
modelResource.GetLifetimeType() != Lifetime.Persistent;
}
internal static void ValidateEndpointPorts(IResource modelResource, EndpointAnnotation endpoint)
{
var modelResourceName = modelResource.Name ?? "(unknown)";
if (modelResource.IsContainer())
{
if (EndpointAnnotation.NormalizePort(endpoint.TargetPort) is null)
{
throw new InvalidOperationException($"The endpoint '{endpoint.Name}' for container resource '{modelResourceName}' must specify the {nameof(EndpointAnnotation.TargetPort)} value");
}
}
else if (!endpoint.IsProxied && endpoint.Port is int && endpoint.Port != endpoint.TargetPort)
{
throw new InvalidOperationException($"The endpoint '{endpoint.Name}' for resource '{modelResourceName}' is not using a proxy, and it has a value of {nameof(EndpointAnnotation.Port)} property that is different from the value of {nameof(EndpointAnnotation.TargetPort)} property. For proxy-less endpoints they must match.");
}
}
/// <summary>
/// Examines the Aspire resource annotations and adds equivalent ServiceProducerAnnotations to the corresponding DCP resource.
/// </summary>
internal static void AddServicesProducedInfo<TDcpResource>(
RenderedModelResource<TDcpResource> appResource,
IEnumerable<IAppResource> appResources)
where TDcpResource : CustomResource, IKubernetesStaticMetadata
{
var modelResource = appResource.ModelResource;
var modelResourceName = modelResource.Name ?? "(unknown)";View on GitHub (pinned to 25830f84bd)