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

Could not parse size limit

Error message

Could not parse size limit `{}`: {}

What it means

This compile-time error fires when the `#[multipart(limit = "...")]` attribute on a field contains a string that cannot be parsed as a human-readable byte size by the `bytesize` crate. The macro attempts `limit.parse::<ByteSize>()` at line 97 and surfaces the underlying parse error with the offending value.

Solutions

  1. Use a valid byte-size string with a unit, e.g. `#[multipart(limit = "10MiB")]`
  2. Check the bytesize crate documentation for supported unit suffixes: B, KB, KiB, MB, MiB, GB, GiB, TB, TiB
  3. Ensure the value is a string literal, not a raw number or expression

Example fix

// before
#[derive(MultipartForm)]
struct Form {
    #[multipart(limit = "5")]
    file: Bytes,
}

// after
#[derive(MultipartForm)]
struct Form {
    #[multipart(limit = "5MiB")]
    file: Bytes,
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the limit string format before using it in the attribute.
// Accepted units (bytesize crate): B, KB, KiB, MB, MiB, GB, GiB, TB, TiB
// Example valid strings: "5MiB", "10MB", "1GiB", "256KiB"
// Note: bare numbers like "5" are NOT valid; always include a unit.

Prevention

When it happens

Trigger: Writing a field attribute like `#[multipart(limit = "10")]` (bare number without unit suffix is not accepted by ByteSize in this version), `#[multipart(limit = "abc")]`, or using an unrecognized unit like `#[multipart(limit = "5xb")]`.

Common situations: Developers who assume raw numbers or non-standard abbreviations are accepted. The `bytesize` crate expects formats like `"5MiB"`, `"10MB"`, `"1GiB"` with an explicit unit.

Related errors


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

Appendix: source

Thrown at actix-multipart-derive/src/lib.rs:99

    };

    let attrs = match MultipartFormAttrs::from_derive_input(&input) {
        Ok(attrs) => attrs,
        Err(err) => return err.write_errors().into(),
    };

    // Parse the field attributes
    let parsed = match fields
        .named
        .iter()
        .map(|field| {
            let rust_name = field.ident.as_ref().unwrap();
            let attrs = FieldAttrs::from_field(field).map_err(|err| err.write_errors())?;
            let serialization_name = attrs.rename.unwrap_or_else(|| rust_name.to_string());

            let limit = match attrs.limit.map(|limit| match limit.parse::<ByteSize>() {
                Ok(ByteSize(size)) => Ok(usize::try_from(size).unwrap()),
                Err(err) => Err(syn::Error::new(
                    field.ident.as_ref().unwrap().span(),
                    format!("Could not parse size limit `{}`: {}", limit, err),
                )),
            }) {
                Some(Err(err)) => return Err(compile_err(err)),
                limit => limit.map(Result::unwrap),
            };

            Ok(ParsedField {
                serialization_name,
                rust_name,
                limit,
                ty: &field.ty,
            })
        })
        .collect::<Result<Vec<_>, TokenStream>>()
    {
        Ok(attrs) => attrs,

View on GitHub (pinned to 4d435abc28)