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

crate types can only be specified for libraries and example

Error message

crate types can only be specified for libraries and example libraries.
Binaries, tests, and benchmarks are always the `bin` crate type

What it means

Thrown by override_rustc_crate_types (src/ops/cargo_compile/mod.rs:1180-1189) when `cargo rustc --crate-type` targets a unit whose TargetKind is neither Lib nor ExampleLib. Binaries, tests, and benchmarks are always the `bin` crate type and cannot be overridden.

Source

Thrown at src/ops/cargo_compile/mod.rs:1184

            unit.profile.clone(),
            unit.kind,
            unit.mode,
            unit.features.clone(),
            unit.rustflags.clone(),
            unit.rustdocflags.clone(),
            unit.links_overrides.clone(),
            unit.is_std,
            unit.dep_hash,
            unit.artifact,
            unit.artifact_target_for_features,
            unit.skip_non_compile_time_dep,
        )
    };
    units[0] = match unit.target.kind() {
        TargetKind::Lib(_) => override_unit(TargetKind::Lib),
        TargetKind::ExampleLib(_) => override_unit(TargetKind::ExampleLib),
        _ => {
            anyhow::bail!(
                "crate types can only be specified for libraries and example libraries.\n\
                Binaries, tests, and benchmarks are always the `bin` crate type"
            );
        }
    };

    Ok(())
}

/// Gets all of the features enabled for a package, plus its dependencies'
/// features.
///
/// Dependencies are added as `dep_name/feat_name` because `required-features`
/// wants to support that syntax.
pub fn resolve_all_features(
    resolve_with_overrides: &Resolve,
    resolved_features: &features::ResolvedFeatures,
    package_set: &PackageSet<'_>,

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Apply --crate-type to the library target instead: `cargo rustc --lib --crate-type cdylib`.
  2. If you need a cdylib, add a [lib] section with `crate-type = ["cdylib"]` in Cargo.toml rather than overriding a bin.
  3. Remove --crate-type from a bin/test/bench invocation.

Example fix

# before
cargo rustc --bin app --crate-type cdylib   # error: bins are always `bin`

# after
cargo rustc --lib --crate-type cdylib
# or in Cargo.toml
[lib]
crate-type = ["cdylib"]
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the selected unit is a Lib or ExampleLib before applying --crate-type.
fn crate_type_applicable(unit: &Unit) -> bool {
    matches!(unit.target.kind(),
        cargo::core::TargetKind::Lib(_) | cargo::core::TargetKind::ExampleLib(_))
}

Type guard

fn is_overridable_kind(t: &cargo::core::Target) -> bool {
    t.is_lib() || t.is_example()
}

Try / catch

if let Err(e) = ops::compile(ws, &opts) {
    if e.to_string().contains("crate types can only be specified") {
        eprintln!("apply --crate-type to a [lib] or example-library target instead");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Calling `cargo rustc --crate-type cdylib --bin foo` (or against a test/bench target). The match on unit.target.kind() falls into the `_` arm and bails.

Common situations: Assuming --crate-type works on any target. Trying to build a cdylib from a binary target instead of the library target. Migrating a bin-only crate and pointing --crate-type at the wrong target.

Related errors


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