Fix error[E0106]: missing lifetime specifier in Rust

intermediate๐Ÿฆ€ Rust2026-03-18| Rust 1.40+ (all editions), any OS (Linux, macOS, Windows)

Error Message

error[E0106]: missing lifetime specifier
#rust#lifetime#reference#annotation

TL;DR

Somewhere in your code there's a reference (&T) inside a struct field, a function signature, or an impl block โ€” and Rust can't figure out how long it lives. The fix is a named lifetime parameter like 'a. It tells the compiler exactly how the reference's validity relates to the surrounding type or function.

// Before (breaks)
struct Config {
    name: &str,  // error[E0106]: missing lifetime specifier
}

// After (fixed)
struct Config<'a> {
    name: &'a str,
}

What triggers this error

Rust tracks how long every reference is valid โ€” that's its memory-safety guarantee, enforced at compile time. When a reference appears in a struct field or a function signature with multiple references, the compiler needs explicit guidance: a lifetime annotation that tells it which reference outlives which.

Three spots trigger this most often:

  • A struct field that holds a reference (&str, &T)
  • A function that returns a reference and takes multiple reference parameters
  • An impl block for a struct that has lifetime parameters

Rust's lifetime elision rules handle many straightforward cases automatically. They don't cover every pattern, though โ€” and when elision can't resolve it, you get error[E0106].

Fix 1 โ€” Struct with a reference field

This is the most common trigger. Add a lifetime parameter to the struct, then annotate each reference field with it.

// Broken
struct Article {
    title: &str,
    body: &str,
}

// Fixed
struct Article<'a> {
    title: &'a str,
    body: &'a str,
}

Any code that creates or uses an Article now carries the lifetime โ€” but in practice, the compiler handles most call sites automatically via elision:

fn print_article(article: &Article) {  // Rust elides here โ€” fine
    println!("{}", article.title);
}

fn main() {
    let title = String::from("Rust Lifetimes");
    let body  = String::from("They keep you safe.");
    let article = Article {
        title: &title,
        body:  &body,
    };
    print_article(&article);
}

Fix 2 โ€” Function returning a reference

Returning a reference from a function requires Rust to know which input it came from. One input reference? Elision handles it. Two or more? You annotate explicitly.

// Broken โ€” Rust can't tell if the return borrows from `a` or `b`
fn longest(a: &str, b: &str) -> &str {
    if a.len() > b.len() { a } else { b }
}

// Fixed โ€” both inputs share lifetime 'a, output lives at most as long
fn longest<'a>(a: &'a str, b: &'a str) -> &'a str {
    if a.len() > b.len() { a } else { b }
}

The 'a annotation says: "the returned reference is valid for as long as both a and b are valid." In practice, that means the shorter of the two lifetimes wins.

Fix 3 โ€” impl block for a struct with lifetimes

Methods on a lifetime-parameterized struct need the same lifetime on the impl keyword itself. Forgetting it is an easy mistake to make.

struct Parser<'a> {
    input: &'a str,
    pos: usize,
}

// Broken
impl Parser {
    fn remaining(&self) -> &str {
        &self.input[self.pos..]
    }
}

// Fixed
impl<'a> Parser<'a> {
    fn remaining(&self) -> &str {
        &self.input[self.pos..]
    }
}

Fix 4 โ€” Consider owning the data instead

Sometimes lifetimes are the wrong tool altogether. If adding 'a everywhere makes the code harder to follow, just own the data outright:

// Instead of borrowing a &str...
struct Config<'a> {
    name: &'a str,
}

// ...own a String
struct Config {
    name: String,
}

You pay a small heap allocation, but the struct is simpler and far easier to pass around. That trade-off usually wins unless you're in a hot path or working directly with borrowed slices from an external API.

Verify the fix

Rebuild the project:

cargo build

No error[E0106] in the output means the lifetimes are resolved. While you're at it, run Clippy to catch any lifetime anti-patterns the compiler might have let through:

cargo clippy

Still unsure which annotation to use? Ask the compiler directly:

rustc --explain E0106

That command prints the full explanation with examples โ€” right in your terminal, no browser needed.

Quick decision guide

  • Struct with &str or &T fields โ†’ add <'a> to the struct and annotate the field.
  • Function returning a reference with multiple input references โ†’ annotate which input the output borrows from.
  • impl block on a struct with lifetimes โ†’ mirror the lifetime params on impl<'a> MyStruct<'a>.
  • Everything else โ†’ consider switching to owned types (String instead of &str, Vec<T> instead of &[T]).

Related Error Notes