Skip to content

Rust Error E0063: Missing Field in Initializer

E0063 means: you’re creating a struct with Name { ... }, but you didn’t give a value for every field. Rust never fills in fields for you, so each one needs a value, even if it’s just 0, false or None. The message lists the missing fields by name, so you know exactly what to add. This is one of the friendliest errors in Rust. (This page is part of Rust compiler errors explained.)

error[E0063]: missing field `email` in initializer of `User`
--> src/main.rs:8:16
|
8 | let user = User {
| ^^^^ missing `email`

This is the program that produces it:

struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let user = User {
name: String::from("Ferris"),
active: true,
// ❌ no `email`
};
println!("{}", user.name);
}

The headline names the missing field (email) and the struct (User). The ^^^^ points at the struct name where you started building it, not at a single line, because the problem is something that isn’t there.

When more fields are missing, rustc lists them in alphabetical order. With two or three, you see them all:

error[E0063]: missing fields `debug`, `retries` and `timeout_secs` in initializer of `Config`

With four or more, it shows three and counts the rest:

error[E0063]: missing fields `debug`, `port`, `retries` and 1 other field in initializer of `Config`
--> src/main.rs:10:18
|
10 | let config = Config {
| ^^^^^^ missing `debug`, `port`, `retries` and 1 other field

“1 other field” means there’s one more. Look at the struct Config definition to see the full list.

It’s like a form where every box is required. You can’t hand it in with the “email” box empty, even if you meant to fill it in later.

In many languages, a missing field quietly becomes null, 0 or an empty string. Then your program runs with a user who has no email, and it breaks somewhere far away, often in production. Rust has no null, and it doesn’t invent values behind your back. A User always has a real email. See Defining and creating a struct.

That doesn’t mean you have to type every field every time. Rust gives you short ways to say “use the defaults” or “copy the rest from this other value”, as the fixes below show. The point is that you choose, and the choice is written in the code.

Choose this most of the time. The field is there for a reason, so give it a real value. If you have a variable with the same name as the field, you can use the shorthand User { name, email, active }.

struct User {
name: String,
email: String,
active: bool,
}
fn main() {
let user = User {
name: String::from("Ferris"),
email: String::from("ferris@example.com"), // ✅ added
active: true,
};
println!("{} <{}> active: {}", user.name, user.email, user.active);
}

Output:

Ferris <ferris@example.com> active: true
▶ Try it Yourself

Fix 2: Derive Default and use ..Default::default()

Section titled “Fix 2: Derive Default and use ..Default::default()”

Choose this when the struct has many fields and most of them have an obvious “empty” value, like settings or options. Add #[derive(Default)] to the struct. Then write only the fields you care about and finish with ..Default::default(). The .. means “take every field I didn’t write from this value”.

#[derive(Debug, Default)]
struct Config {
host: String,
port: u16,
debug: bool,
timeout_secs: u64,
retries: u8,
}
fn main() {
let config = Config {
host: String::from("localhost"),
port: 8080,
..Default::default() // ✅ debug, timeout_secs and retries get defaults
};
println!("{:?}", config);
}

Output:

Config { host: "localhost", port: 8080, debug: false, timeout_secs: 0, retries: 0 }
▶ Try it Yourself

The derived defaults are 0 for numbers, false for bool, an empty String and None for an Option. If 0 is a bad default (a timeout of 0 seconds probably is), write impl Default for Config yourself with better values. See Default: a sensible starting value.

If you forget the #[derive(Default)], the error changes to E0277: the trait bound `Config: Default` is not satisfied, with help: consider annotating `Config` with `#[derive(Default)]`.

Choose this when you create the struct in many places, or when some fields always start the same way. Put the full struct literal in one function, and call that function everywhere else. When you add a field later, you only update new, not every call site.

struct Player {
name: String,
score: u32,
level: u8,
}
impl Player {
fn new(name: &str) -> Player {
Player {
name: name.to_string(),
score: 0, // every new player starts at 0...
level: 1, // ...on level 1
}
}
}
fn main() {
let ana = Player::new("Ana");
let mut bo = Player::new("Bo");
bo.score += 50;
println!("{}: score {}, level {}", ana.name, ana.score, ana.level);
println!("{}: score {}, level {}", bo.name, bo.score, bo.level);
}

Output:

Ana: score 0, level 1
Bo: score 50, level 1
▶ Try it Yourself

The struct literal inside new still needs every field, so a forgotten field shows up there as E0063. That’s fine: you fix it once. See Constructor-style functions.

Fix 4: Copy the rest from another value with ..other

Section titled “Fix 4: Copy the rest from another value with ..other”

Choose this when you already have a similar value and want a copy with a few changes. ..base takes every field you didn’t write from base:

#[derive(Debug, Clone)]
struct Theme {
name: String,
font_size: u8,
dark: bool,
}
fn main() {
let base = Theme { name: String::from("Default"), font_size: 14, dark: false };
// only `name` and `dark` change, the rest comes from `base`
let night = Theme { name: String::from("Night"), dark: true, ..base };
// `..base` would move `name` out of base, so clone it to keep using base
let large = Theme { font_size: 20, ..base.clone() };
println!("{:?}", night);
println!("{:?}", large);
println!("{:?}", base);
}

Output:

Theme { name: "Night", font_size: 14, dark: true }
Theme { name: "Default", font_size: 20, dark: false }
Theme { name: "Default", font_size: 14, dark: false }
▶ Try it Yourself

One thing to know: ..base moves fields like String out of base. In night that’s fine, because we wrote our own name, so only the Copy fields (font_size) came from base. In large, name would come from base, so we use ..base.clone() to keep base usable. If you skip the clone and use base later, you get E0382.

Sometimes a field really can be empty: a phone number a user hasn’t given yet, a nickname, an end date. Make that field an Option. You still have to write it (Rust doesn’t fill in None for you), but None is now an honest, allowed value. See Option.

#[derive(Debug, Default)]
struct Contact {
name: String,
email: String,
phone: Option<String>, // may be missing
nickname: Option<String>,
}
fn main() {
let a = Contact {
name: String::from("Ana"),
email: String::from("ana@example.com"),
phone: None, // written out: "no phone yet"
nickname: Some(String::from("Annie")),
};
// with Default, every Option you leave out becomes None
let b = Contact { name: String::from("Bo"), ..Default::default() };
println!("{} phone: {:?}, nickname: {:?}", a.name, a.phone, a.nickname);
println!("{} email: {:?}, phone: {:?}", b.name, b.email, b.phone);
}

Output:

Ana phone: None, nickname: Some("Annie")
Bo email: "", phone: None
▶ Try it Yourself

Notice b.email is "". That’s the trap with Default: a required field quietly becomes empty. Use Option only for things that are truly optional, and keep required fields like email as plain types that you always fill in.

Right after you add a field to a struct. You add created_at to User, and suddenly every User { ... } in the project gives E0063. That’s Rust helping you: each place is one you need to think about. A new constructor (Fix 3) keeps this list short.

Enum variants with named fields. Shape::Rectangle { width: 2.0 } gives missing field `height` in initializer of `Shape`. Note that the message names the enum, not the variant. Fix: give every field of that variant a value. See Enums can hold data.

A function that returns a struct. In fn new_player(name: &str) -> Player { Player { name: name.to_string(), score: 0 } }, the arrow points at Player inside the function, with missing `level`. Fix: add level to that literal.

Quick check

1. rustc says: missing fields a, b, c and 2 other fields. How many fields are missing?

2. Your struct has an Option<String> field you don't need yet. What do you write for it?

3. What does Config { port: 80, ..Default::default() } need in order to compile?

Score: 0 / 3