microsoft/aspire · error · DistributedApplicationException

Java application ' ' cannot be published because the…

Error message

Java application '{resource.Name}' cannot be published because the OpenTelemetry agent path '{authored}' is a Windows path, which cannot resolve inside the Linux image the application is published to. Use a path inside the application directory so it is copied into the image, or an absolute path the base image or a mount provides at runtime.

What it means

TryGetBuildProducedAgentPath (used by Dockerfile generation and build-context ignore computation) rejects a Windows-rooted OpenTelemetry agent path. The published image is Linux, so a path like "C:\otel\javaagent.jar" would leak into JAVA_TOOL_OPTIONS as -javaagent:C:\... and crash the JVM at startup with an error that names the agent but not the cause. Throwing at publish time surfaces the problem early; the jar and wrapper checks already reject Windows paths, and this keeps the agent consistent.

Solutions

  1. Use a path relative to the application directory, e.g. WithOtelAgent("otel/javaagent.jar"), so the jar is copied into the image.
  2. Or use a Linux absolute path that the base image or a mount provides at runtime, e.g. "/opt/otel/javaagent.jar".
  3. Remove drive letters and backslashes; normalize to forward slashes.

Example fix

// before
.WithOtelAgent(@"C:\tools\otel\javaagent.jar")
// after
.WithOtelAgent("otel/javaagent.jar");
Defensive patterns

Strategy: validation

Validate before calling

if (System.Text.RegularExpressions.Regex.IsMatch(agentPath, @"^[A-Za-z]:[\\/]|^\\\\"))
    throw new ArgumentException("Otel agent path must be a relative app-directory path or a Linux absolute path, not a Windows path");

Try / catch

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

Prevention

When it happens

Trigger: Calling WithOtelAgent with a Windows-rooted path (drive letter or backslash-rooted, e.g. "C:\agents\javaagent.jar") on any platform, then publishing (Write or BuildContextIgnoreContent).

Common situations: Developing on Windows and authoring an absolute local path for the agent jar; paths auto-composed from Windows-specific environment variables or user-profile directories.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

        if (!resource.TryGetLastAnnotation<JavaOtelAgentAnnotation>(out var annotation))
        {
            return false;
        }

        var authored = JavaHostingExtensions.ResolveOtelAgentPath(resource, annotation);

        if (IsPathRootedOnAnyPlatform(authored))
        {
            // A POSIX absolute path is a legitimate arrangement: the base image or a mount provides the
            // agent, and rewriting it would break that. A Windows-rooted path cannot be, because the
            // image the AppHost publishes to is Linux. Leaving it alone puts "-javaagent:C:\..." into
            // JAVA_TOOL_OPTIONS, and the JVM then dies during VM initialization with an error that
            // names the agent but not the reason. The jar artifact and the wrapper already reject
            // Windows-rooted paths on every platform; this keeps the agent consistent with them.
            if (IsWindowsRooted(authored))
            {
                throw new DistributedApplicationException(
                    $"Java application '{resource.Name}' cannot be published because the OpenTelemetry agent " +
                    $"path '{authored}' is a Windows path, which cannot resolve inside the Linux image the " +
                    "application is published to. Use a path inside the application directory so it is copied " +
                    "into the image, or an absolute path the base image or a mount provides at runtime.");
            }

            return false;
        }

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

        // Strip a single leading "./" only. Trimming the '.' and '/' characters as a set would turn
        // "../agents/otel.jar" into "agents/otel.jar" and emit a COPY for a path that was never in the
        // build context, failing the container build with a path the author never wrote.
        if (normalized.StartsWith("./", StringComparison.Ordinal))
        {
            normalized = normalized[2..];

View on GitHub (pinned to 25830f84bd)