---
title: "1.7 Compiler errors and how to read them"
description: "The anatomy of a Rust compiler error: error codes, spans, labels, help lines, and the habit of reading the first error first."
url: "https://learnrust.net/chapter-1/reading-compiler-errors/"
last_updated: "2026-06-11"
---

# 1.7 Compiler errors and how to read them

You're a handful of lessons into writing real statements, which means you're now generating compiler errors at a healthy clip. Good. This lesson is about reading them, and it isn't a digression: in Rust, the error messages are half the documentation. The difference between a frustrating week and a productive one is mostly whether you read errors or just *react* to them.

## The anatomy of an error

Here's a program with a one-letter typo, the kind your fingers will produce daily:

```rust
fn main() {
    let score = 100;
    println!("final score: {}", scoer);
}
```

```
error[E0425]: cannot find value `scoer` in this scope
 --> src/main.rs:3:33
  |
3 |     println!("final score: {}", scoer);
  |                                 ^^^^^
  |
help: a local variable with a similar name exists
  |
3 -     println!("final score: {}", scoer);
3 +     println!("final score: {}", score);
  |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0425`.
```

Every Rust error has the same skeleton, so learn it once:

- **The headline.** `error[E0425]: cannot find value `scoer` in this scope`. One sentence stating the problem. `E0425` is an **error code**, a stable ID for this *kind* of mistake.
- **The location.** `--> src/main.rs:3:33`: file, line, column.
- **The span.** The little excerpt of your own code with `^^^^^` carets underneath, pointing at the exact characters in question. Longer errors have several spans with labels, each marking a place that contributes to the problem.
- **The help.** `help:` lines propose a concrete fix; here the compiler noticed that `scoer` looks one keyboard fumble away from `score`, and writes the suggestion as a tiny before-and-after diff: the `-` line is yours, the `+` line is the proposed replacement. `note:` lines, when present, explain the rule being applied.

Read in that order: what, where, suggestion. For typo-grade errors, the help line *is* the fix, and your job is just to believe it.

## Mismatched types, a preview of your future

The error you'll see most often in Rust isn't the typo; it's E0308, mismatched types. Here's an honest specimen:

```rust
fn main() {
    let x: i32 = "hello";
    println!("{x}");
}
```

```
error[E0308]: mismatched types
 --> src/main.rs:2:18
  |
2 |     let x: i32 = "hello";
  |            ---   ^^^^^^^ expected `i32`, found `&str`
  |            |
  |            expected due to this

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.
```

This one shows off the multi-span format: one label under the value ("expected `i32`, found `&str`") and another under the type annotation explaining *why* an `i32` was expected there. The compiler isn't just rejecting the program; it's showing its reasoning. `&str` is the type of string literals, which you'll meet formally in chapter 5; you can already read the gist, which is the point.

That last line of both transcripts is a real offer, by the way. Run `rustc --explain E0308` in your terminal and you get a short article about that error class: what causes it, with example code, and how it's usually fixed. It's the rare error message with further reading attached.

## Read the first error first

One mistake can produce a cascade. If your typo confuses the compiler about what a line means, every later line that depends on it may also "fail," and a single missing brace can produce a screenful. The discipline, the same one lesson [0.9](https://learnrust.net/chapter-0/a-few-common-problems/) prescribed: scroll to the **first** error, fix only it, recompile. It's common for five errors to become zero.

Warnings ride along with errors in the same format, and you already know the policy from lesson [0.11](https://learnrust.net/chapter-0/warnings-lints-and-clippy/): handle them as they appear, and use the `_unused` underscore convention when something is unused on purpose.

> **Key insight**
>
> Here's the course's thesis, one lesson early enough to matter. In C++, the scariest failures *compile cleanly* and misbehave at runtime, sometimes only on Tuesdays: reads of freed memory, off-the-end array writes, garbage values. Safe Rust moves nearly all of that to compile time. The same underlying mistakes still happen (you're human), but they arrive as error messages with file, line, carets, and a suggested fix, instead of as 2 a.m. mysteries. The strict compiler that's slowing you down this week is the thing that makes the failures *legible*. Learning to read its output isn't coping; it's the skill.

> **Tip**
>
> Your editor shows these same errors inline as red squiggles (that's rust-analyzer from lesson [0.7](https://learnrust.net/chapter-0/setting-up-a-code-editor/), running the checks as you type). Hover for the message. But when an error is longer than a hover box, the terminal's `cargo build` output, with its full spans and notes, is easier to read. Don't debug big errors through a tooltip keyhole.

## Quiz time

**Question #1**

In a Rust error message, what's the difference between a `help:` line and a `note:` line?

<details class="solution">
<summary>Show solution</summary>

`help:` proposes a concrete fix, often with the exact code to write. `note:` explains the rule or reasoning behind the error. Fix from the help, learn from the note.

</details>

**Question #2**

You compile and get fourteen errors. What's the move?

<details class="solution">
<summary>Show solution</summary>

Read and fix the *first* one only, then recompile. Later errors are often echoes of the first mistake and vanish once it's fixed.

</details>

**Question #3**

Without compiling, predict the headline of the error this produces, as specifically as you can:

```rust
fn main() {
    let widht = 800;
    println!("width is {}", width);
}
```

<details class="solution">
<summary>Show solution</summary>

Error E0425: cannot find value `width` in this scope, with a help line suggesting the similarly-named `widht`. (The compiler points at the *use* of the name it can't find. The actual typo is in the `let` line, a "where it noticed vs. where it is" case from lesson [1.1](https://learnrust.net/chapter-1/statements-and-program-structure/). The deeper fix is renaming the variable, not the use.)

</details>

**Question #4**

What does `rustc --explain E0308` do, and when would you reach for it?

<details class="solution">
<summary>Show solution</summary>

It prints an extended explanation of that error class (mismatched types), with examples and typical fixes. Reach for it when the short message isn't landing and you want the article-length version.

</details>

Next up: what you're allowed to *name* things, and the short list of words Rust keeps for itself.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
