jdx/mise · error

content-level SLSA verification does not support symlink…

Error message

content-level SLSA verification does not support symlink archive entry: {}

What it means

During zip content hashing for SLSA verification, mise skips directories but rejects any symlink entries, since content verification hashes regular file data only and symlinks cannot be verified the same way (and may be attack vectors). The member name is included in the error.

Solutions

  1. Repackage the zip with real files instead of symlinks
  2. Create the zip without symlink preservation so targets are stored as files
  3. Use tar.* (if verification supported it) or disable content verification for this asset

Example fix

// before
zip -r tool.zip tool/   # preserves symlinks
// after
zip -r tool.zip -D tool/   # or dereference/replace symlinks before zipping
Defensive patterns

Strategy: try-catch

Validate before calling

// list zip entries and reject symlink metadata before verification
for (const e of listZip(archive)) {
  if (e.isSymlink) throw new Error("symlink entry: " + e.name);
}

Type guard

function isRegularZipEntry(e) { return !e.isSymlink && !e.isDirectory; }

Try / catch

try { verifySlsaZip(a) } catch (e) { if (/symlink archive entry/.test(e.message)) { repackZipWithoutSymlinks(a); } else throw e; }

Prevention

When it happens

Trigger: SLSA content verification of a zip archive that stores symlinks among its entries.

Common situations: Zips created on Unix with `zip -y` preserving symlinks; GitHub-generated source archives; packaging pipelines that include symlinked libs.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/b231c19c649b248e. Report an issue: GitHub.

Appendix: source

Thrown at src/file.rs:2712

    validate_archive_content_files(files)
}

fn archive_content_files_zip(
    archive_path: &Path,
    strip_components: usize,
) -> Result<Vec<ArchiveContent>> {
    let f = File::open(archive_path)?;
    let mut archive = ZipArchive::new(f)
        .wrap_err_with(|| format!("failed to open zip archive: {}", display_path(archive_path)))?;
    let mut files = Vec::new();

    for i in 0..archive.len() {
        let mut file = archive.by_index(i)?;
        if file.is_dir() {
            continue;
        }
        if file.is_symlink() {
            bail!(
                "content-level SLSA verification does not support symlink archive entry: {}",
                file.name()
            );
        }
        let enclosed_name = file.enclosed_name().ok_or_else(|| {
            eyre::eyre!(
                "content-level SLSA verification rejected unsafe zip path: {}",
                file.name()
            )
        })?;
        let name = normalize_archive_content_path(&enclosed_name, strip_components)?;
        let sha256 = sha256_reader(&mut file)?;
        files.push(ArchiveContent { name, sha256 });
    }

    validate_archive_content_files(files)
}

View on GitHub (pinned to 533346cc37)