microsoft/aspire · error · InvalidOperationException
RemoteImageName must be set.
Error message
RemoteImageName must be set.
What it means
GetFullRemoteImageNameAsync combines the registry, remote image name, and tag into the fully qualified image name used when pushing. The library requires RemoteImageName to be explicitly set because it cannot derive a sane default and pushing without it would produce an invalid repository path. If it is null or empty an InvalidOperationException is thrown before any registry interaction.
Solutions
- Set RemoteImageName on the ContainerImagePushOptions before calling GetFullRemoteImageNameAsync.
- Validate options in your pipeline before invoking push so empty image names fail fast with a clear message.
- If the name comes from configuration, add a startup check that rejects empty values.
Example fix
// before
var options = new ContainerImagePushOptions { Registry = registry, RemoteImageTag = "v1" };
var full = await options.GetFullRemoteImageNameAsync(registry);
// after
var options = new ContainerImagePushOptions { Registry = registry, RemoteImageName = "myapp/api", RemoteImageTag = "v1" };
var full = await options.GetFullRemoteImageNameAsync(registry); Defensive patterns
Strategy: validation
Validate before calling
if (options is null) throw new ArgumentNullException(nameof(options));
if (string.IsNullOrWhiteSpace(options.RemoteImageName))
throw new InvalidOperationException("RemoteImageName must be set before resolving the full remote image name."); Try / catch
try
{
var full = await options.GetFullRemoteImageNameAsync(registry, ct);
}
catch (InvalidOperationException ex)
{
logger.LogError(ex, "Push options incomplete: {Message}", ex.Message);
throw new PipelineConfigException("Image push options missing RemoteImageName.", ex);
} Prevention
- Always set RemoteImageName together with Registry when building ContainerImagePushOptions.
- Centralize push-option construction in one factory that validates required fields.
- Add a startup config check rejecting empty image names.
- Unit-test the options factory with a missing-field case.
When it happens
Trigger: Calling GetFullRemoteImageNameAsync on a ContainerImagePushOptions instance whose RemoteImageName property was never assigned (or set to ""), e.g. building push options programmatically and forgetting the image name while only setting registry and tag.
Common situations: Constructing push options in custom publishing pipelines; migrating code that only set the local image name; building a registry push step dynamically where the image name comes from configuration that returned empty; tests calling the API directly with a partially initialized options object.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- AllocatedEndpoint must use the same network as the…
- Ambiguous tags - a tag was provided on both the 'tag' and…
- Anonymous volumes cannot be read-only.
- Bind mounts must specify a source path.
- Bind mounts must specify an absolute path.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e846f921382f6b2a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/ApplicationModel/ContainerImagePushOptions.cs:79
/// <remarks>
/// <para>
/// This method retrieves the registry endpoint asynchronously and combines it with the remote image name and tag.
/// If <see cref="RemoteImageTag"/> is <c>null</c> or empty, "latest" is used as the default tag.
/// </para>
/// <para>
/// The <see cref="RemoteImageName"/> value is parsed to determine if it contains an override for the registry
/// host or repository. If the <see cref="RemoteImageName"/> contains a host component (detected by the presence
/// of a dot in the first segment), that host will be used instead of the registry endpoint. Otherwise, the
/// registry endpoint is used and the <see cref="IContainerRegistry.Repository"/> (if set) is prepended to the image name.
/// </para>
/// </remarks>
public async Task<string> GetFullRemoteImageNameAsync(
IContainerRegistry registry,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(RemoteImageName))
{
throw new InvalidOperationException("RemoteImageName must be set.");
}
ArgumentNullException.ThrowIfNull(registry);
var tag = string.IsNullOrEmpty(RemoteImageTag) ? "latest" : RemoteImageTag;
// Parse the RemoteImageName to check if it contains a host override
var (host, imagePath) = ParseImageReference(RemoteImageName);
if (!string.IsNullOrEmpty(host))
{
// RemoteImageName contains a host, use it directly instead of the registry endpoint
return $"{host}/{imagePath}:{tag}";
}
// Use the registry endpoint
var registryEndpoint = await registry.Endpoint
.GetValueAsync(cancellationToken)View on GitHub (pinned to 25830f84bd)