actix/actix-web · error · actix_multipart::Error

Required field is missing

Error message

Required field is missing: {_0}

What it means

Error::MissingField(String) is raised in FieldGroupReader::from_state for the plain T impl (form/mod.rs:190) when, after consuming the whole multipart stream, the state map does not contain an entry for a required (non-Option) field. It means no part with that name was ever sent, so construction of the struct fails with a 400 Bad Request. Option<T> fields never trigger it because they default to None.

Solutions

  1. Make the field optional: Option<T> so an absent part yields None instead of an error.
  2. Ensure the client actually sends a part with the exact expected name (mind #[multipart(rename = "...")] mappings).
  3. Provide a clearer error to the client via MultipartFormConfig::error_handler.

Example fix

// before
struct Upload { title: Text<String>, file: TempFile } // missing title => 400

// after
struct Upload { title: Option<Text<String>>, file: TempFile }
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the client sends all required parts; on the server make optional
struct Form {
    title: Option<Text<String>>, // absent => None, no error
    file: TempFile,             // still required
}

Try / catch

match form_result {
    Err(e) => {
        if let Some(actix_multipart::MultipartError::MissingField(name)) =
            e.as_error::<actix_multipart::MultipartError>()
        {
            return HttpResponse::BadRequest().body(format!("missing field: {name}"));
        }
        return Err(e);
    }
    Ok(form) => handle(form),
}

Prevention

When it happens

Trigger: A client submits a multipart form that omits a part the struct declares as a required T: FieldReader. For struct { title: Text<String>, file: TempFile }, a request with only the file part yields MissingField("title").

Common situations: Frontend form missing a required input; field name typo between client and server; conditional form fields not sent; renaming a Rust field without updating #[multipart(rename)] or the client.

Related errors


AI-assisted analysis of actix/actix-web@7ae209e4a4 (2026-08-09). Data as JSON: /api/errors/da948f96662b61a2. Report an issue: GitHub.

Appendix: source

Thrown at actix-multipart/src/error.rs:91

    #[display("Stream is not consumed")]
    NotConsumed,

    /// Form field handler raised error.
    #[display("An error occurred processing field '{name}': {source}")]
    Field {
        name: String,
        source: actix_web::Error,
    },

    /// Duplicate field found (for structure that opted-in to denying duplicate fields).
    #[display("Duplicate field found: {_0}")]
    #[from(ignore)]
    DuplicateField(#[error(not(source))] String),

    /// Required field is missing.
    #[display("Required field is missing: {_0}")]
    #[from(ignore)]
    MissingField(#[error(not(source))] String),

    /// Unknown field (for structure that opted-in to denying unknown fields).
    #[display("Unknown field: {_0}")]
    #[from(ignore)]
    UnknownField(#[error(not(source))] String),
}

/// Return `BadRequest` for `MultipartError`.
impl ResponseError for Error {
    fn status_code(&self) -> StatusCode {
        match &self {
            Error::Field { source, .. } => source.as_response_error().status_code(),
            Error::ContentTypeIncompatible => StatusCode::UNSUPPORTED_MEDIA_TYPE,
            _ => StatusCode::BAD_REQUEST,
        }
    }
}

View on GitHub (pinned to 7ae209e4a4)