microsoft/aspire · error · InvalidOperationException
Volume ' ' on resource ' ' does not declare a mount path.
Error message
Volume '{VolumeName}' on resource '{context.Resource.Name}' does not declare a mount path. What it means
VolumeMountBindingAnnotation.ResolvePath computes the path a volume mount is exposed at. In publish mode or for ContainerResource, the MountPath must be declared; if VolumeName is set but MountPath is null, ResolvePath throws InvalidOperationException stating the volume does not declare a mount path. Without a mount path the host cannot know where inside the container/compute the volume should be attached.
Solutions
- Specify the mount path when adding the volume, e.g. WithVolume("mydata", "/data") instead of WithVolume("mydata").
- For project resources only running locally in run mode, confirm you are not accidentally in publish mode where MountPath is required.
- If you own the annotation construction, set the MountPath property on the VolumeMountAnnotation before resolution.
Example fix
// before
var pg = builder.AddPostgres("pg").WithDataVolume("pgdata"); // no mount path
// after
var pg = builder.AddPostgres("pg")
.WithVolume("pgdata", "/var/lib/postgresql/data"); Defensive patterns
Strategy: validation
Validate before calling
// Ensure every volume annotation has a mount path before publish/container run:
if (volumeAnnotation.MountPath is null && (context.ExecutionContext.IsPublishMode || resource is ContainerResource))
throw new InvalidOperationException($"Volume '{volumeAnnotation.VolumeName}' needs an explicit mount path."); Try / catch
try
{
var path = volumeMountAnnotation.ResolvePath(context);
}
catch (InvalidOperationException ex)
{
logger.LogError(ex, "Volume mount path missing: {Message}", ex.Message);
} Prevention
- Always pass an explicit mount path to WithVolume/WithDataVolume when the resource runs as a container or will be published.
- Audit volume usage when switching a project resource to containerized or publish scenarios.
- Use the WithVolume(name, mountPath) overload rather than the name-only overload for containers.
When it happens
Trigger: Calling WithVolume/WithPersistentVolume-style APIs (WithPersistentVolumeCore/WithVolumeCore call ResolvePath) where the volume annotation has a VolumeName but no MountPath, in publish mode or on a container resource.
Common situations: Using WithVolume(name) overload without specifying the container mount path when targeting containers or publish; refactoring from run-mode-only volume usage into containerized/published scenarios where MountPath becomes mandatory; copying volume config from a project resource to a container resource.
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
- Resource ' ' binds volume ' ' to environment variable ' '…
- Anonymous volumes cannot be read-only.
- ASPIRERADIUS084
- 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/8b9141664dd00579.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/ApplicationModel/VolumeMountBindingAnnotation.cs:83
/// <summary>
/// Resolves the storage path the workload should use for the current execution mode.
/// </summary>
/// <param name="context">The environment callback context being evaluated.</param>
/// <returns>
/// <see cref="MountPath"/> when publishing or when the workload runs as a container, and otherwise a
/// local host directory.
/// </returns>
/// <exception cref="InvalidOperationException">
/// Thrown when the deployed mount path is required but this binding does not declare one.
/// </exception>
public string ResolvePath(EnvironmentCallbackContext context)
{
ArgumentNullException.ThrowIfNull(context);
if (context.ExecutionContext.IsPublishMode || context.Resource is ContainerResource)
{
var mountPath = MountPath ?? throw new InvalidOperationException(
$"Volume '{VolumeName}' on resource '{context.Resource.Name}' does not declare a mount path.");
if (context.ExecutionContext.IsPublishMode)
{
ThrowIfEnvironmentCannotMount(context);
}
return mountPath;
}
// Prefer this binding's own resolver. The sibling scan below only exists for the name-match
// composition, where the mount and the compute environment binding are spelled as two separate
// calls and the mount-declaring annotation therefore carries no resolver of its own.
//
// Scanning unconditionally would alias distinct volumes, because VolumeName is not a unique key —
// two compute environments can each declare a volume under the same name, and every binding would
// then select the last resolver and point at one environment's store. Aspire.Hosting.Kubernetes
// rejects that shape up front, but this annotation is public and shared across computeView on GitHub (pinned to 25830f84bd)