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

Required field is missing: {_0}

Error message

Required field is missing: {_0}

What it means

MultipartError::MissingField(String) (multipart/error.rs:87-89) is returned by the FieldGroupReader for a plain scalar type T in form/mod.rs:186-191 when from_state cannot find the field name in the accumulated state — i.e. the client never sent a part with that name. It maps to HTTP 400 BadRequest. Only plain T fields (not Option<T> or Vec<T>) are required; Option and Vec default to None/empty.

Source

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

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

    /// Form field handler raised error.
    #[display("An error occurred processing field: {name}")]
    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 937960ca67)

Solutions

  1. Make the field optional: change T to Option<T> if the part is legitimately skippable.
  2. Ensure the client sends a part with the exact name (Content-Disposition: form-data; name="<field>").
  3. Verify the field name in the struct matches the form input name attribute exactly (case-sensitive).

Example fix

// before: required scalar
#[derive(MultipartForm)]
struct Form { avatar: TempFile }

// after: optional
#[derive(MultipartForm)]
struct Form { avatar: Option<TempFile> }
Defensive patterns

Strategy: validation

Validate before calling

// Client-side: verify all required fields are present before submit.
const required = ['username', 'avatar'];
const fd = new FormData(form);
const missing = required.filter(f => !fd.has(f));
if (missing.length) { alert('Missing: ' + missing.join(', ')); return }

Try / catch

// The extractor yields 400 MissingField; map it to a friendly message.
async fn handler(MultipartForm(form): MultipartForm<Form>) -> Result<HttpResponse, Error> {
    Ok(HttpResponse::Ok().finish())
}
// wrap with a custom error handler that downcasts to MultipartError::MissingField
// to render the missing field name in the 400 response.

Prevention

When it happens

Trigger: A multipart/form-data submission omits a part whose name matches a non-Option, non-Vec field of the handler struct. The extractor iterates all incoming fields, none populate the required name, and from_state returns MissingField.

Common situations: Frontend form missing a required input, a file upload where the file input had no name attribute, or a renamed backend field that the client was not updated to match.

Related errors


AI-assisted analysis of actix/actix-web@937960ca67 (2026-08-06). Data as JSON: /data/errors/da948f96662b61a2.json. Report an issue: GitHub.