rust-lang/cargo · error

cannot publish with `open-namespaces`

Error message

cannot publish with `open-namespaces`

What it means

Thrown by prepare_toml_for_publish when the manifest's cargo_features include 'open-namespaces'. The open-namespaces unstable feature relaxes package naming rules but is incompatible with registry publishing — published crate names must conform to the standard namespace rules. The check scans all cargo_features entries for an exact match.

Solutions

  1. Remove 'open-namespaces' from cargo-features in Cargo.toml before publishing.
  2. Use a standard crate name that satisfies cargo's naming rules (alphanumeric, underscores, hyphens).
  3. If you need the feature for development, gate it behind a non-published manifest or remove it in a publish pre-processing step.

Example fix

# before
cargo-features = ["open-namespaces"]

[package]
name = "weird/name"

# after
[package]
name = "weird-name"
Defensive patterns

Strategy: validation

Validate before calling

fn manifest_safe_for_publish(toml: &str) -> Result<(), String> {
    if toml.contains("open-namespaces") {
        return Err("remove `open-namespaces` from cargo-features before publishing".into());
    }
    Ok(())
}

Type guard

fn publish_ready_features(toml: &toml::Value) -> bool {
    toml.get("cargo_features").and_then(|f| f.as_array())
        .map(|arr| !arr.iter().any(|v| v.as_str() == Some("open-namespaces")))
        .unwrap_or(true)
}

Prevention

When it happens

Trigger: A manifest with cargo-feares = ["open-namespaces"] (or in [cargo_features]) that is being prepared for publish via prepare_for_publish / prepare_for_publish. The feature is detected in the flat-mapped feature list and the operation bails before producing the publishable manifest.

Common situations: A developer experiments with open-namespaces locally then runs `cargo publish` without removing the feature flag. A nightly-only workflow leaks into a publish pipeline. The feature was added for local testing and forgotten.

Related errors


AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11). Data as JSON: /api/errors/350219ce68a6a3e0. Report an issue: GitHub.

Appendix: source

Thrown at src/workspace/parser/mod.rs:2994

/// Prepares the manifest for publishing.
// - Path and git components of dependency specifications are removed.
// - License path is updated to point within the package.
fn prepare_toml_for_publish(
    me: &manifest::TomlManifest,
    ws: &Workspace<'_>,
    package_root: &Path,
    packaged_files: Option<&[PathBuf]>,
) -> CargoResult<manifest::TomlManifest> {
    let gctx = ws.gctx();

    if me
        .cargo_features
        .iter()
        .flat_map(|f| f.iter())
        .any(|f| f == "open-namespaces")
    {
        anyhow::bail!("cannot publish with `open-namespaces`")
    }

    let mut package = me.package().unwrap().clone();
    package.workspace = None;
    // Validates if build script file is included in package. If not, warn and ignore.
    if let Some(custom_build_scripts) = package.normalized_build().expect("previously normalized") {
        let mut included_scripts = Vec::new();
        for script in custom_build_scripts {
            let path = Path::new(script).to_path_buf();
            let included = packaged_files.map(|i| i.contains(&path)).unwrap_or(true);
            if included {
                let path = path
                    .into_os_string()
                    .into_string()
                    .map_err(|_err| anyhow::format_err!("non-UTF8 `package.build`"))?;
                let path = normalize_path_string_sep(path);
                included_scripts.push(path);
            } else {

View on GitHub (pinned to 98a09e7e7d)