microsoft/aspire · error · DistributedApplicationException

Resource ' ' cannot resolve the ' ' persistent-volume path…

Error message

Resource '{resource.Name}' cannot resolve the '{environmentVariableName}' persistent-volume path in run mode. Only project, executable, and container resources are supported.

What it means

In run mode, Kubernetes persistent-volume bindings are emulated by resolving a local path environment variable. Only ProjectResource, ExecutableResource, and ContainerResource have a supported local execution story, so any other resource type bound to a persistent volume throws DistributedApplicationException.

Solutions

  1. Bind the persistent volume only to project, executable, or container resources.
  2. Implement local path resolution support for the custom resource type, or gate the volume binding behind publish mode.
  3. Remove the volume binding if the resource does not need local persistent storage.

Example fix

// before
var custom = builder.AddResource<MyCustomResource>("custom").WithPersistentVolume(...);
// after
var svc = builder.AddContainer("svc", "image").WithPersistentVolume(...);
Defensive patterns

Strategy: type-guard

Validate before calling

bool supportsVolumes = resource is ProjectResource or ExecutableResource or ContainerResource;

Type guard

bool SupportsKubernetesVolumes(IResource r) => r is ProjectResource or ExecutableResource or ContainerResource;

Try / catch

try { RunAppHostAsync(); } catch (DistributedApplicationException ex) when (ex.Message.Contains("persistent-volume path in run mode")) { /* remove or re-target volume binding */ }

Prevention

When it happens

Trigger: Calling WithVolume/WithPersistentVolume-style binding on a resource that is not a project, executable, or container (e.g. a custom IResource or connection-resource type) and running the AppHost in run mode.

Common situations: Custom resource types in an AppHost binding Kubernetes volumes; third-party resources that support volumes only at publish time being run locally.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Kubernetes/KubernetesEnvironmentExtensions.cs:118

            .ToArray();
    }

    private static void ValidateRunModePersistentVolumeBindings(PersistentVolumeBinding[] bindings)
    {
        ValidateRunModeVolumeNamesAreUnambiguous(bindings);

        foreach (var (resource, annotation) in bindings)
        {
            // The env can be spelled on the binding or on a separate name-matched mount, and both make
            // the resource resolve the same local store path, so an unsupported resource shape has to
            // be rejected for either spelling. Without this, a custom compute resource still receives
            // the store path while the compatibility check below treats it as publish-only.
            var environmentVariableName = GetLocalPathEnvironmentVariableName(resource, annotation);

            if (environmentVariableName is not null &&
                resource is not ProjectResource and not ExecutableResource and not ContainerResource)
            {
                throw new DistributedApplicationException(
                    $"Resource '{resource.Name}' cannot resolve the '{environmentVariableName}' persistent-volume path in run mode. " +
                    $"Only project, executable, and container resources are supported.");
            }
        }

        ValidateRunModeBackingStoreCompatibility(bindings);
    }

    private static void ValidateRunModeVolumeNamesAreUnambiguous(PersistentVolumeBinding[] bindings)
    {
        // Only run mode can reach this. Publish mode registers each volume with AddResource, so a second
        // volume sharing a name fails global resource-name uniqueness while the model is still being
        // built. Run mode hands back a CreateResourceBuilder that never registers the volume, so the
        // collision survives to here.
        //
        // Both run-mode paths key off the volume name alone — the local path lookup in
        // VolumeMountBindingAnnotation.ResolvePath and the container mount rewrite in
        // ApplyRunModeContainerVolumeName — so two distinct volumes sharing a name on one resource would

View on GitHub (pinned to 25830f84bd)