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
- Remove 'open-namespaces' from cargo-features in Cargo.toml before publishing.
- Use a standard crate name that satisfies cargo's naming rules (alphanumeric, underscores, hyphens).
- 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
- Strip unstable cargo-features (especially open-namespaces) before `cargo publish`.
- Run `cargo publish --dry-run` to catch publish-time rejections early.
- Keep a separate publish-ready manifest if you need open-namespaces for local dev.
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
- cache expected 4 bytes for index schema version
- config.json not found
- failed to verify the checksum of
- failed to verify the checksum of
- found an override with a non-locked list
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)