Ir al contenido

Error E0463 de Rust: can't find crate (crate no encontrado)

E0463 significa que el compilador fue a buscar un crate (una biblioteca) entero y volvió con las manos vacías. Normalmente tu código tiene una línea extern crate para un crate que no está en Cargo.toml. A veces el crate que falta es el propio std, y eso pasa cuando compilas para otro tipo de máquina y todavía no has instalado ese target. Los dos casos se arreglan rápido, y no necesitas entender cómo funciona un linker para aplicar la solución. Esta página forma parte de la guía de errores del compilador.

error[E0463]: can't find crate for `rand`
--> src/main.rs:1:1
|
1 | extern crate rand;
| ^^^^^^^^^^^^^^^^^^ can't find crate

“Can’t find crate for rand” quiere decir “no se encuentra el crate rand”.

Este es el programa que lo produce, en un proyecto recién creado con cargo new y sin nada bajo [dependencies]:

extern crate rand;
fn main() {
let roll = rand::random_range(1..=6);
println!("You rolled {roll}");
}

La segunda forma habitual no tiene número de línea, porque ninguna línea de tu código pide std. Todos los programas lo necesitan:

error[E0463]: can't find crate for `std`
|
= note: the `aarch64-unknown-linux-gnu` target may not be installed
= help: consider downloading the target with `rustup target add aarch64-unknown-linux-gnu`

La note dice que quizá el target aarch64-unknown-linux-gnu no está instalado, y el help te da el comando para descargarlo. Lo obtienes con cargo build --target aarch64-unknown-linux-gnu (Linux en ARM de 64 bits, como una Raspberry Pi) cuando solo tienes instalado el target de tu propia máquina. La solución que necesitas depende del nombre del crate y de la note::

Lo que ves Lo que suele haber fallado Solución
can't find crate for `rand` en una línea extern crate el crate no está en Cargo.toml Solución 1
lo mismo, en código antiguo con #[macro_use] código escrito antes de la edición 2018 Solución 2
can't find crate for `std` + target may not be installed compilas para un target que rustup no ha descargado Solución 3
crate name using dashes are not valid junto a E0463 un - en el nombre del crate dentro de tu código Solución 4

extern crate rand; le dice al compilador “enlaza en este programa la biblioteca compilada que se llama rand”. El compilador no descarga nada ni busca en internet. Solo mira las bibliotecas que le pasa Cargo, y Cargo solo le pasa los crates que aparecen en Cargo.toml. Si rand no está ahí, no hay ninguna biblioteca rand en la lista, y por eso sale E0463.

El caso de std es la misma idea, un nivel más abajo. La biblioteca estándar también es una biblioteca compilada, y rustup instala una copia por cada target. Tu toolchain normal solo tiene la copia para tu propio ordenador. Si pides una compilación para ARM, el compilador busca una copia de std para ARM que no está.

Es como una receta que dice “usa la harina del armario”. Si nadie compró harina, el cocinero no puede empezar, por muy buena que sea la receta.

Rust no tiene una carpeta global y compartida de bibliotecas instaladas, como el pip install de Python o un node_modules para todo el sistema. Cada proyecto dice exactamente qué usa en Cargo.toml, con versiones, y Cargo compila esos crates para ese proyecto. Por eso el mismo proyecto se compila igual en tu portátil, en el ordenador de un compañero y en CI. Un crate que no está escrito ahí simplemente no existe para tu código.

extern crate es sobre todo un resto de Rust 2015. Desde la edición 2018, todos los crates de Cargo.toml están disponibles automáticamente, así que el código moderno escribe simplemente use rand::random_range;. Todavía te encontrarás extern crate en tutoriales antiguos y respuestas de Stack Overflow, y de ahí vienen la mayoría de los E0463. Hoy, sin la dependencia, una línea use da E0432 y una ruta en tu código da E0433. La misma causa, con otro código.

Mira Cargo y crates para ver cómo funcionan las dependencias, y Herramientas de Rust para las toolchains y los targets.

Elige esta cuando el crate que falta viene de crates.io, como rand, regex o serde_json. Es el caso más común. Ejecuta esto en la carpeta que contiene Cargo.toml:

Terminal window
cargo add rand

Cargo añade la versión más reciente por ti:

[dependencies]
rand = "0.10.3"

Solo con eso se arregla E0463. Ya que estás, borra la línea extern crate rand;; no la necesitas desde la edición 2018 (mira edition = en Cargo.toml). Esta versión imprime una comprobación en lugar de la tirada, para que la salida sea siempre la misma:

fn main() {
let roll = rand::random_range(1..=6);
println!("La tirada está entre 1 y 6: {}", (1..=6).contains(&roll));
}

Salida:

La tirada está entre 1 y 6: true
▶ Pruébalo tú mismo

El código antiguo también puede llamar a funciones que cambiaron entre versiones. Si cargo add arregla E0463 pero después te sale E0425 o E0432 con algo como thread_rng, revisa la documentación del crate para la versión que tienes. Mira Añadir una dependencia con cargo add.

Solución 2: Cambiar las líneas extern crate antiguas por use

Sección titulada «Solución 2: Cambiar las líneas extern crate antiguas por use»

Elige esta cuando copiaste código anterior a 2018. Suele empezar con un bloque como este, y cada línea puede dar E0463:

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[derive(Serialize)]
struct Order {
item: String,
qty: u32,
}
error[E0463]: can't find crate for `serde_derive`
--> src/main.rs:2:1
|
2 | extern crate serde_derive;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
error[E0463]: can't find crate for `serde_json`
--> src/main.rs:3:1
|
3 | extern crate serde_json;
| ^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate

Rust no encuentra ni serde_derive ni serde_json. No añadas serde_derive como un crate aparte. Hoy las macros derive vienen con serde cuando activas su feature derive:

Terminal window
cargo add serde --features derive
cargo add serde_json

Después borra el bloque extern crate e importa lo que usas con una línea use normal. Tampoco hace falta #[macro_use]:

use serde::Serialize;
#[derive(Serialize)]
struct Order {
item: String,
qty: u32,
}
fn main() {
let order = Order { item: String::from("manzana"), qty: 3 };
println!("{}", serde_json::to_string(&order).unwrap());
}

Salida:

{"item":"manzana","qty":3}
▶ Pruébalo tú mismo

Si una línea extern crate nombra un crate que tu código en realidad no usa, simplemente borra la línea. La lección JSON con serde muestra la configuración moderna completa.

Solución 3: Instalar el target con rustup target add

Sección titulada «Solución 3: Instalar el target con rustup target add»

Elige esta cuando el error habla de std (o de core) y la note: dice que quizá el target no está instalado. Copia el nombre del target de la línea help::

Terminal window
rustup target add aarch64-unknown-linux-gnu
rustup target list --installed # comprueba lo que tienes ahora

Después vuelve a compilar con el mismo --target. Un target es el tipo de máquina para la que compilas, escrito como un “triple” del estilo aarch64-unknown-linux-gnu o wasm32-unknown-unknown. rustup descarga el std ya compilado para ese target, y el E0463 desaparece.

Dos notas. Primero, para muchos targets ese no es el último paso: compilar un programa completo para otro sistema operativo suele necesitar también un linker para esa plataforma, y eso es otro error distinto. Segundo, si el proyecto tiene un rust-toolchain.toml, ejecuta el comando dentro de la carpeta del proyecto, para que rustup añada el target a la toolchain que ese proyecto usa de verdad. Mira Componentes y targets y la lección de WebAssembly, un target que probablemente usarás.

Solución 4: Escribir los guiones como guiones bajos en el código

Sección titulada «Solución 4: Escribir los guiones como guiones bajos en el código»

Elige esta cuando el nombre del crate tiene un guion, como serde-json o tracing-subscriber. En Cargo.toml y en la línea de comandos el guion está bien. En el código de Rust, un - es un signo menos, así que el nombre siempre se escribe con _. El código antiguo con un guion da esto:

error: crate name using dashes are not valid in `extern crate` statements
--> src/main.rs:1:14
|
1 | extern crate serde-json;
| ^^^^^^^^^^ dash-separated idents are not valid
|
help: if the original crate name uses dashes you need to use underscores in the code
|
1 - extern crate serde-json;
1 + extern crate serde_json;
|
error[E0463]: can't find crate for `serde_json`

El primer error dice que los nombres de crate con guiones no son válidos en extern crate, y el help te pide usar guiones bajos en el código. rustc ya lee el nombre como serde_json, así que el E0463 de debajo solo aparece cuando el crate además falta en Cargo.toml. En una línea use, un guion da otro mensaje distinto, expected one of `::`, `;`, or `as`, found `-` (se esperaba ::, ; o as, pero se encontró -). La solución es la misma en todas partes: haz cargo add del crate si hace falta, y escribe _ en el código:

use serde_json::json;
fn main() {
let order = json!({ "item": "manzana", "qty": 3 });
println!("{order}");
}

Salida:

{"item":"manzana","qty":3}
▶ Pruébalo tú mismo

La misma regla se aplica a tu propio paquete: un proyecto llamado shop-app se importa como shop_app desde su main.rs y desde sus tests.

Al ejecutar rustc main.rs directamente. rustc por sí solo no lee Cargo.toml, así que incluso después de cargo add rand, rustc --edition 2021 src/main.rs sigue diciendo can't find crate for `rand` para una línea extern crate rand; (y E0432 para una línea use rand::...). Solución: compila con cargo run o cargo build, que pasan tus dependencias al compilador.

Un crate que está en [dev-dependencies]. Las dev-dependencies (las que se añaden con cargo add --dev) solo existen para los tests, los ejemplos y los benchmarks. Usar una desde el código normal da E0463 con extern crate, o E0433 con una ruta. Solución: muévela a [dependencies] con cargo remove --dev serde_json y después cargo add serde_json.

Placas embebidas sin sistema operativo. Para un target como thumbv7em-none-eabihf, instalarlo no basta, porque no tiene std en absoluto. La nota cambia para decirlo:

error[E0463]: can't find crate for `std`
|
= note: the `thumbv7em-none-eabihf` target may not support the standard library
= note: `std` is required by `shop` because it does not declare `#![no_std]`

Las notas dicen que ese target quizá no admite la biblioteca estándar, y que shop necesita std porque no declara #![no_std]. Solución: escribe el programa como #![no_std], lo que también significa nada de println! y tu propio manejador de panic. El Embedded Rust Book (en inglés) te guía paso a paso.

  • E0432: unresolved import (importación no resuelta), lo que da una línea use cuando el crate falta en Cargo.toml.
  • E0433: failed to resolve (no se pudo resolver), lo que da una ruta como rand::rng() cuando falta el crate.
  • E0603: el crate se encontró, pero el elemento que quieres de él es privado.
  • crate name using dashes are not valid: este no tiene código de error; escribe _ en lugar de - (Solución 4).
  • Todos los errores del compilador: la lista completa de páginas de errores.

Comprueba lo aprendido

1. Un código antiguo empieza con extern crate regex; y te sale E0463. ¿Cuál es la mejor solución en un proyecto con la edición 2021?

2. cargo build --target wasm32-unknown-unknown dice que no encuentra el crate std y que quizá el target no está instalado. ¿Qué ejecutas?

3. Tu Cargo.toml tiene tracing-subscriber = "0.3". ¿Cómo escribes el nombre del crate en el código de Rust?

Puntuación: 0 / 3