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

Duplicate field found: {_0}

Error message

Duplicate field found: {_0}

What it means

MultipartError::DuplicateField(String) (multipart/error.rs:82-84) is returned by the MultipartForm extractor (form/mod.rs:89-92 and 168-172) when the same form field name is submitted more than once AND that field's duplicate_field policy is DuplicateField::Deny. It maps to HTTP 400 BadRequest via the ResponseError impl (error.rs:98-106). Only affects structs using the #[multipart(duplicate_field = "deny")] attribute.

Source

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

    Parse(ParseError),

    /// HTTP payload error.
    #[display("Payload error")]
    Payload(PayloadError),

    /// 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 {

View on GitHub (pinned to 937960ca67)

Solutions

  1. If duplicates are legitimate, type the field as Vec<T> (always allows duplicates) or set duplicate_field to "ignore"/"replace".
  2. If duplicates are invalid, fix the client to send the field exactly once.
  3. Inspect the raw multipart body to find which field name is duplicated.

Example fix

// before: scalar field rejects duplicates
#[derive(MultipartForm)]
struct Form { #[multipart(limit = "1KiB")] email: String }

// after: accept duplicates, keep the last
#[derive(MultipartForm)]
struct Form {
    #[multipart(limit = "1KiB", duplicate_field = "replace")]
    email: String,
}
Defensive patterns

Strategy: validation

Validate before calling

// On the client, ensure each non-list field is sent exactly once.
// Inspect the FormData before submit:
function countFields(form, name) {
  return [...form.getAll(name)].length;
}
if (countFields(form, 'email') > 1) { /* dedupe or warn */ }

Try / catch

// In the handler, the MultipartForm extractor returns actix_web::Error (400).
async fn upload(MultipartForm(form): MultipartForm<Form>) -> impl Responder {
    HttpResponse::Ok().body("ok")
}
// duplicate field -> 400 BadRequest with the field name in the error body

Prevention

When it happens

Trigger: A multipart/form-data POST contains two parts with the same Content-Disposition name (e.g. two 'email' fields), and the handler struct declared that field as a scalar type (T or Option<T>) with duplicate_field=deny. The FieldGroupReader for T/Option<T> hits the Deny branch.

Common situations: Frontend bug submitting the same field twice, duplicate file inputs, or a misconfigured form. Switching a field from Vec<T> to T changes a previously-tolerant handler into a strict one.

Related errors


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