microsoft/aspire · error · DistributedApplicationException

Java application ' ' cannot be published because its…

Error message

Java application '{resource.Name}' cannot be published because its jarPath '{annotation.JarPath}' is outside the directory the build runs in. The path is resolved against the application directory inside the container, so it has to name a file the build produces there. Pass a jarPath relative to the application directory, or use WithJarArtifact to name the published artifact separately from the one run locally.

What it means

During Dockerfile generation for publish mode, TryGetBuildOutputJarPath validates the JavaBuildToolAnnotation.JarPath. A jarPath that is rooted (e.g. C:\... or /...) or contains a '..' segment resolves outside the application directory inside the container build, so generation throws DistributedApplicationException rather than producing a broken COPY. The jar must be a relative path within the build context.

Solutions

  1. Change jarPath to a path relative to the application directory, e.g. "target/app.jar" (Maven) or "build/libs/app.jar" (Gradle).
  2. If you need the locally-run jar and the published jar to differ, use WithJarArtifact to name the published artifact separately.
  3. Remove any leading slashes, drive letters, or '..' segments from jarPath.

Example fix

// before
java.WithJarBuild(JavaBuildTool.Maven, jarPath: "/home/dev/target/app-1.0.jar");
// after
java.WithJarBuild(JavaBuildTool.Maven, jarPath: "target/app-1.0.jar");
Defensive patterns

Strategy: validation

Validate before calling

var normalized = jarPath.Replace('\\', '/');
if (Path.IsPathRooted(jarPath) || normalized.Split('/').Contains(".."))
    throw new ArgumentException("jarPath must be relative to the application directory, e.g. target/app.jar");

Try / catch

try { await PublishAsync(...); } catch (DistributedApplicationException ex) when (ex.Message.Contains("jarPath")) { Console.Error.WriteLine(ex.Message); return 1; }

Prevention

When it happens

Trigger: Calling WithJarBuild (or setting JarPath on JavaBuildToolAnnotation) with an absolute path like "/app/target/app.jar" or "C:\build\app.jar", or a relative path like "../out/app.jar", then running the publish/Dockerfile generation.

Common situations: Copying a local machine's absolute jar path into the resource configuration; assuming paths resolve on the host instead of inside the build container; using '..' to point at a sibling module's output directory.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Java/JavaDockerfileGenerator.cs:355

            return false;
        }

        // Container paths are POSIX even when the AppHost authored a Windows-style relative path.
        var normalized = annotation.JarPath.Replace('\\', '/');

        if (normalized.StartsWith("./", StringComparison.Ordinal))
        {
            normalized = normalized[2..];
        }

        if (normalized.Length == 0)
        {
            return false;
        }

        if (IsPathRootedOnAnyPlatform(annotation.JarPath) || normalized.Split('/').Contains(".."))
        {
            throw new DistributedApplicationException(
                $"Java application '{resource.Name}' cannot be published because its jarPath " +
                $"'{annotation.JarPath}' is outside the directory the build runs in. The path is resolved " +
                "against the application directory inside the container, so it has to name a file the " +
                "build produces there. Pass a jarPath relative to the application directory, or use " +
                "WithJarArtifact to name the published artifact separately from the one run locally.");
        }

        jarPath = normalized;

        return true;
    }

    /// <summary>
    /// Normalizes an authored path for use inside the container build, rejecting anything that would
    /// reach outside the build context.
    /// </summary>
    /// <remarks>
    /// The build context is the application directory, so only files under it are uploaded to the daemon.

View on GitHub (pinned to 25830f84bd)