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.)
The error message
Section titled “The error message”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);}What it means
Section titled “What it means”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.
Why Rust does this
Section titled “Why Rust does this”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.
How to fix it
Section titled “How to fix it”Fix 1: Add the missing field
Section titled “Fix 1: Add the missing field”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"), active: true, }; println!("{} <{}> active: {}", user.name, user.email, user.active);}Output:
Ferris <[email protected]> active: trueFix 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 }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)]`.
Fix 3: Write a constructor, new
Section titled “Fix 3: Write a constructor, new”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 1Bo: score 50, level 1The 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 }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.
When Option fields help
Section titled “When Option fields help”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"), 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: NoneNotice 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.
Where you’ll usually see it
Section titled “Where you’ll usually see it”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.
Related errors
Section titled “Related errors”- E0560: struct has no field named x: the opposite, a field you wrote that the struct doesn’t have. A typo often gives both at once.
- E0559: variant has no field named x: the same wrong-name mistake for enum variants.
- E0277: trait bound not satisfied: you wrote
..Default::default()but the struct doesn’t deriveDefault. - E0451: field is private: the struct comes from another module and some fields are private, so you can’t fill them in. If you leave a private field out, you don’t get E0063 but “cannot construct
Accountwith struct literal syntax due to private fields”. Either way, use the module’snewfunction. - E0382: use of moved value: you used a value after
..valuemoved its fields out. - All compiler errors explained
Quick check
Section titled “Quick check”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
Read more
Section titled “Read more”- E0063 — Rust error codes index: the official explanation of this error.
- Defining and Instantiating Structs — The Rust Book: struct literals, the field init shorthand and struct update syntax.
Default— Rust standard library:#[derive(Default)], writing your ownimpl Default, and..Default::default().- Struct expressions — The Rust Reference: the exact rules for
Name { field: value }and..base. - Constructors — Rust API Guidelines: why Rust code uses
newfunctions for building structs.