jdx/mise · error

content-level SLSA verification does not support symlink arc

Error message

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

What it means

The zip branch of content-level SLSA verification explicitly rejects symlink entries (file.is_symlink()): a symlink's target is not content mise can hash and could point outside the archive. Directories are skipped; every remaining entry must be a regular file.

Source

Thrown at src/file.rs:2521

    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 9dcfcaa0dc)

Solutions

  1. Fall back to artifact-level verification for that tool
  2. If you produce the zip, repack with symlinks dereferenced (avoid zip -y, or dereference before zipping)
  3. Use a tar.gz variant only if it also contains no links (the tar path rejects them too)
Defensive patterns

Strategy: validation

Validate before calling

let mut za = zip::ZipArchive::new(std::fs::File::open(&archive)?)?;
for i in 0..za.len() {
    let f = za.by_index(i)?;
    if f.is_symlink() {
        anyhow::bail!("zip contains symlink entry {}; content-level SLSA will fail closed", f.name());
    }
}

Try / catch

match archive_content_files(&archive, ExtractionFormat::Zip, strip) {
    Ok(files) => verify_subjects(&files)?,
    Err(e) if e.to_string().contains("symlink archive entry") => {
        warn!("zip contains symlinks; falling back to artifact-level verification: {e:#}");
        verify_artifact_level(&archive)?;
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: A .zip asset containing symlink entries (stored with unix mode bits) is processed by archive_content_files while content-level verification is enabled.

Common situations: Zips built on Linux/macOS that preserve symlinks, e.g. a bin directory with versioned symlinks created by zip without dereferencing.

Related errors


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