microsoft/aspire · error · InvalidOperationException

Tar entry ' ' would extract outside the destination…

Error message

Tar entry '{entry.Name}' would extract outside the destination directory.

What it means

During bundle payload extraction, BundleService validates every tar entry's resolved full path against the normalized destination directory to block path traversal ('..' or absolute-name entries). If an entry would extract outside the destination, it throws InvalidOperationException naming the offending entry. This is a security guard against malicious or malformed bundle archives.

Solutions

  1. Reinstall the Aspire CLI from the official source to get a known-good bundle payload.
  2. Rebuild the bundle with a packaging script that emits relative, containerized entry names (no leading '/', no '..').
  3. Verify the bundle's checksum against the published value to detect tampering or corruption.
  4. If you control extraction, keep the existing guard and reject the archive rather than bypassing it.

Example fix

// before (bad packaging script)
tar -czf bundle.tar.gz /abs/path/files  // entries carry absolute names
// after
tar -czf bundle.tar.gz -C payload .     // entries are relative to the payload root
Defensive patterns

Strategy: validation

Validate before calling

// pre-validate archive entry names before extraction
foreach (var entry in archiveEntries)
{
    if (Path.IsPathRooted(entry.Name) || entry.Name.Split('/', '\\').Contains(".."))
        throw new InvalidOperationException($"Unsafe tar entry: {entry.Name}");
}

Type guard

static bool IsSafeEntryName(string name) =>
    !string.IsNullOrEmpty(name) && !Path.IsPathRooted(name) && !name.Split('/', '\\').Contains("..");

Try / catch

try { await ExtractPayloadAsync(dest, ct); }
catch (InvalidOperationException ex) when (ex.Message.Contains("would extract outside")) { /* reject/tamper-check the bundle; reinstall from a trusted source */ }

Prevention

When it happens

Trigger: Extracting a tar.gz whose entry name contains '..' segments, absolute paths, or symlink targets that resolve outside the destination directory (line ~898 check).

Common situations: A corrupted or hand-crafted/tampered bundle payload; a bundle built with absolute or ../-relative entry names by a faulty packaging script; MITM-substituted payload if the bundle was downloaded insecurely.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Cli/Bundles/BundleService.cs:898

            if (slashIndex < 0)
            {
                continue; // Top-level directory entry itself, skip
            }

            var relativePath = name[(slashIndex + 1)..];
            if (string.IsNullOrEmpty(relativePath))
            {
                continue;
            }

            var fullPath = Path.GetFullPath(Path.Combine(destinationPath, relativePath));
            var normalizedDestination = Path.GetFullPath(destinationPath);

            // Guard against path traversal attacks (e.g., entries containing ".." segments)
            if (!fullPath.StartsWith(normalizedDestination + Path.DirectorySeparatorChar, StringComparison.Ordinal) &&
                !fullPath.Equals(normalizedDestination, StringComparison.Ordinal))
            {
                throw new InvalidOperationException($"Tar entry '{entry.Name}' would extract outside the destination directory.");
            }

            switch (entry.EntryType)
            {
                case TarEntryType.Directory:
                    Directory.CreateDirectory(fullPath);
                    break;

                case TarEntryType.RegularFile:
                    var dir = Path.GetDirectoryName(fullPath);
                    if (dir is not null)
                    {
                        Directory.CreateDirectory(dir);
                    }
                    await entry.ExtractToFileAsync(fullPath, overwrite: true, cancellationToken);

                    // Preserve Unix file permissions from tar entry (e.g., execute bit)
                    if (!environment.IsWindows() && entry.Mode != default)

View on GitHub (pinned to 25830f84bd)