{"record":{"id":"6874233580d7d18e","repo":"microsoft/aspire","slug":"java-application-resourcename-cannot-be-published-because","errorCode":null,"errorMessage":"Java application '{resourceName}' cannot be published because {description} '{authored}' is outside the build context '{appDirectory}'. Only files under the application directory are uploaded to the container build.","messagePattern":"Java application '(.+?)' cannot be published because (.+?) '(.+?)' is outside the build context '(.+?)'\\. Only files under the application directory are uploaded to the container build\\.","errorType":"exception","errorClass":"DistributedApplicationException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting.Java/JavaDockerfileGenerator.cs","lineNumber":433,"sourceCode":"    /// does, rather than only when the build happens to run on Windows.\n    /// </remarks>\n    private static bool IsWindowsRooted(string path)\n        => path.StartsWith('\\\\')\n            || (path.Length >= 2 && char.IsAsciiLetter(path[0]) && path[1] == ':');\n\n    private static string NormalizeContextRelativePath(string authored, string resourceName, string appDirectory, string description)\n    {\n        // Container paths are POSIX even when the AppHost authored a Windows-style relative path.\n        var normalized = authored.Replace('\\\\', '/');\n\n        if (normalized.StartsWith(\"./\", StringComparison.Ordinal))\n        {\n            normalized = normalized[2..];\n        }\n\n        if (IsPathRootedOnAnyPlatform(authored) || normalized.Split('/').Contains(\"..\"))\n        {\n            throw new DistributedApplicationException(\n                $\"Java application '{resourceName}' cannot be published because {description} '{authored}' \" +\n                $\"is outside the build context '{appDirectory}'. Only files under the application \" +\n                \"directory are uploaded to the container build.\");\n        }\n\n        if (normalized.Any(char.IsWhiteSpace))\n        {\n            throw new DistributedApplicationException(\n                $\"Java application '{resourceName}' cannot be published because {description} '{authored}' \" +\n                \"contains whitespace, which a Dockerfile COPY instruction cannot express. Move it to a \" +\n                \"path without spaces.\");\n        }\n\n        return normalized;\n    }\n\n    private static JavaBuildTool? DetectBuildToolForPublish(JavaAppResource resource, string appDirectory)\n        => JavaBuildToolResolver.Detect(","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting.Java/JavaDockerfileGenerator.cs#L415-L451","documentation":"NormalizeContextRelativePath validates authored paths (e.g. prebuilt jar paths) against the Docker build context, which is the application directory. A rooted path or one containing '..' would require files outside the build context, which are not uploaded to the container build, so it throws DistributedApplicationException at publish time.","triggerScenarios":"Calling TryGetPrebuiltJarPath (via Dockerfile generation) with a prebuilt jar path that is absolute (\"/libs/app.jar\", \"D:\\jars\\app.jar\") or that escapes the app directory (\"../shared/app.jar\").","commonSituations":"Referencing a jar from a sibling project directory; using an absolute host path for a prebuilt artifact; restructuring directories so the jar now sits above the app directory.","solutions":["Move or copy the jar into the application directory and reference it with a relative path.","Remove '..' segments; if the artifact lives in a shared location, copy it into the app directory during your build.","Ensure the path is relative with forward slashes, e.g. \"libs/app.jar\"."],"exampleFix":"// before\n.WithJarArtifact(\"../shared-libs/payments.jar\")\n// after\n.WithJarArtifact(\"libs/payments.jar\"); // jar copied under the app directory","handlingStrategy":"validation","validationCode":"var normalized = path.Replace('\\\\', '/');\nif (Path.IsPathRooted(path) || normalized.Split('/').Contains(\"..\"))\n    throw new ArgumentException($\"{path} must be a relative path inside the application directory (Docker build context)\");","typeGuard":null,"tryCatchPattern":"try { await PublishAsync(...); } catch (DistributedApplicationException ex) when (ex.Message.Contains(\"build context\")) { Console.Error.WriteLine(ex.Message); return 1; }","preventionTips":["Keep all artifacts referenced by published Java resources under the application directory.","Copy shared artifacts into the app directory during your build instead of referencing '..' paths.","Use forward-slash relative paths in resource configuration."],"tags":["java","docker","build-context","path-validation"],"backgroundTag":"path-traversal-blocked","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}