rust-lang/cargo · error · anyhow::Error

invalid inclusion of reserved file name {} in package source

Error message

invalid inclusion of reserved file name {} in package source

What it means

During `cargo package`/`cargo publish`, build_ar_list walks every source file to be archived. The filenames .cargo_vcs_info.json and Cargo.toml.orig are reserved - Cargo itself generates them inside the .crate archive - so any such file appearing in the package source list is treated as an illegal inclusion and rejected. This prevents user files from shadowing Cargo's generated metadata.

Source

Thrown at src/ops/cargo_package/mod.rs:515

#[tracing::instrument(skip_all)]
fn build_ar_list(
    ws: &Workspace<'_>,
    pkg: &Package,
    src_files: Vec<PathEntry>,
    vcs_info: Option<vcs::VcsInfo>,
    include_lockfile: bool,
) -> CargoResult<Vec<ArchiveFile>> {
    let mut result = HashMap::default();
    let root = pkg.root();
    for src_file in &src_files {
        let rel_path = src_file.strip_prefix(&root)?;
        check_filename(rel_path, &mut ws.gctx().shell())?;
        let rel_str = rel_path.to_str().ok_or_else(|| {
            anyhow::format_err!("non-utf8 path in source directory: {}", rel_path.display())
        })?;
        match rel_str {
            "Cargo.lock" => continue,
            VCS_INFO_FILE | ORIGINAL_MANIFEST_FILE => anyhow::bail!(
                "invalid inclusion of reserved file name {} in package source",
                rel_str
            ),
            _ => {
                result
                    .entry(UncasedAscii::new(rel_str))
                    .or_insert_with(Vec::new)
                    .push(ArchiveFile {
                        rel_path: rel_path.to_owned(),
                        rel_str: rel_str.to_owned(),
                        contents: FileContents::OnDisk(src_file.to_path_buf()),
                    });
            }
        }
    }

    // Ensure we normalize for case insensitive filesystems (like on Windows) by removing the
    // existing entry, regardless of case, and adding in with the correct case

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Delete the offending file from your source tree: `rm .cargo_vcs_info.json Cargo.toml.orig`
  2. Add it to .gitignore and ensure no build step writes it into the package
  3. If you extracted a previous .crate into your repo, remove all generated artifacts

Example fix

# before: src/.cargo_vcs_info.json exists -> cargo package fails
# after
rm src/.cargo_vcs_info.json Cargo.toml.orig 2>/dev/null
cargo package
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
const RESERVED: &[&str] = &[".cargo_vcs_info.json", "Cargo.toml.orig"];
fn ensure_no_reserved_files(root: &Path) -> Result<(), String> {
    for entry in walkdir::WalkDir::new(root) {
        let entry = entry.map_err(|e| e.to_string())?;
        if entry.file_type().is_file() {
            if let Some(name) = entry.file_name().to_str() {
                if RESERVED.contains(&name) {
                    return Err(format!("reserved file in tree: {}", entry.path().display()));
                }
            }
        }
    }
    Ok(())
}

Type guard

import { walkSync } from 'fs';
import { basename } from 'path';
const RESERVED = new Set(['.cargo_vcs_info.json', 'Cargo.toml.orig']);
function treeHasNoReserved(root: string): boolean {
  for (const f of walkSync(root)) { if (RESERVED.has(basename(f.path))) return false; }
  return true;
}

Prevention

When it happens

Trigger: Shipping a file literally named `.cargo_vcs_info.json` or `Cargo.toml.orig` inside the package source tree (e.g. copied in by a build script, vendored manually, or committed by mistake). The match arm at cargo_package/mod.rs:515 catches them.

Common situations: A previous `cargo package` output was unzipped into the source tree and not cleaned; a macro/build script copies archive metadata back into src/; CI artifacts committed by accident; users trying to 'pre-seed' VCS info.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/40750f304921ad98.json. Report an issue: GitHub.