microsoft/aspire · error · DistributedApplicationException
The Rust app ' ' builds from ' ', but its symbolic links…
Error message
The Rust app '{resourceName}' builds from '{manifestPath}', but its symbolic links could not be fully resolved. Publishing stops rather than accepting a partially canonicalized path. What it means
ValidateManifestPath calls PathNormalizer.TryResolveSymlinks on both the app working directory and the full manifest path; if either cannot be fully canonicalized it throws this DistributedApplicationException. Publishing needs fully resolved paths so it can verify the manifest lies inside the build context and compute the Docker COPY path; accepting a partially canonicalized path could silently produce a wrong or unsafe build context. The library stops rather than guessing.
Solutions
- Inspect and fix the symlinks in the app directory path — remove dangling or cyclic links (ls -l / readlink -f)
- Replace symlinked paths with the real target directory when configuring the resource
- Verify the manifest path and working directory exist and are readable before publishing
Example fix
// before
ln -s /nonexistent/target ../rust-app # dangling symlink
builder.AddRustApp("app", "../rust-app");
// after
ln -s /real/path/rust-app ../rust-app # or use the real path directly
builder.AddRustApp("app", "/real/path/rust-app"); Defensive patterns
Strategy: validation
Validate before calling
if (!PathNormalizer.TryResolveSymlinks(Path.GetFullPath(appDir), out _)) throw new InvalidOperationException("App directory contains unresolvable symlinks."); Type guard
bool HasResolvableSymlinks(string dir) => PathNormalizer.TryResolveSymlinks(Path.GetFullPath(dir), out _);
Try / catch
try { await PublishAsync(appModel); } catch (DistributedApplicationException ex) when (ex.Message.Contains("symbolic links")) { log.LogError(ex, "Unresolvable symlinks in Rust app path"); } Prevention
- Run readlink -f (or equivalent) on the app directory before configuring the resource
- Remove dangling or cyclic symlinks from project paths
- Prefer real paths over symlinked checkouts in CI environments
When it happens
Trigger: Publishing a RustAppResource when TryResolveSymlinks fails for the working directory or manifest path — e.g. dangling symlinks, symlink loops, or filesystem entries that disappear while canonicalizing (common with linked monorepo checkouts or network/overlay filesystems).
Common situations: App directory reached through a broken or cyclic symlink; macOS/Linux symlinked project folders (e.g. ~/projects -> /volume/projects) where resolution hits an unreadable link; container/overlay filesystems where the link target does not exist.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- The Rust app ' ' builds from the absolute path ' '…
- Ensure ' ' is installed and available on PATH.
- The published Rust app
- The published Rust app
- The Rust app ' ' targets ' ', which requires container…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/56245a32490f688e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Rust/RustDockerfileGenerator.cs:227
if (Path.IsPathRooted(manifestPath))
{
throw new DistributedApplicationException(
$"The Rust app '{resourceName}' builds from the absolute path '{manifestPath}'. Publishing needs a path " +
$"relative to its app directory '{workingDirectory}'.");
}
var platformManifestPath = OperatingSystem.IsWindows()
? manifestPath.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar)
: manifestPath;
var filesystemWorkingDirectory = Path.GetFullPath(workingDirectory);
var filesystemManifest = Path.GetFullPath(platformManifestPath, workingDirectory);
if (!PathNormalizer.TryResolveSymlinks(filesystemWorkingDirectory, out var canonicalWorkingDirectory)
|| !PathNormalizer.TryResolveSymlinks(filesystemManifest, out var canonicalManifest))
{
throw new DistributedApplicationException(
$"The Rust app '{resourceName}' builds from '{manifestPath}', but its symbolic links could not be " +
"fully resolved. Publishing stops rather than accepting a partially canonicalized path.");
}
// Resolve aliases first so equivalent roots such as /var and /private/var become lexically related.
// Then only enumerate entries below the build context to recover the spelling Docker will copy.
canonicalManifest = ResolveFilesystemCasing(canonicalWorkingDirectory, canonicalManifest);
var relativeManifest = Path.GetRelativePath(canonicalWorkingDirectory, canonicalManifest);
if (Path.IsPathRooted(relativeManifest)
|| relativeManifest == ".."
|| relativeManifest.StartsWith($"..{Path.DirectorySeparatorChar}", StringComparison.Ordinal)
|| relativeManifest.StartsWith($"..{Path.AltDirectorySeparatorChar}", StringComparison.Ordinal))
{
throw new DistributedApplicationException(
$"The Rust app '{resourceName}' builds from '{manifestPath}', which resolves outside its app directory " +
$"'{workingDirectory}'. Only the app directory is copied into the image.");View on GitHub (pinned to 25830f84bd)