Skip to content

bug: multipart/formdata boundary is not sent in header #885

Description

@Kludex

Originally opened by @Anton-Shutik on 2025-03-03 14:01:37 in encode/httpx

python==3.12
httpx==0.28.1

I'm having and issue while sending data with "Content-Type": "multipart/form-data", while sending same data with "Content-Type": "multipart/form-data; boundary=WebKitFormBoundary7MA4YWxkTrZu0gW" works fine.

Take a look at full example:

from curlify2 import Curlify

headers = {
    "Authorization": f"Bearer {self.api_token}",
    "Content-Type": "multipart/form-data",
    # "Content-Type": "multipart/form-data; boundary=WebKitFormBoundary7MA4YWxkTrZu0gW",
}

# Prepare form data as tuples for multipart/form-data
files = [("image_url", (None, url)) for url in photo_urls]

async with httpx.AsyncClient() as client:
    try:
        req = await client.post(endpoint, headers=headers, files=files, )
        response = Curlify(req.request)
        print("#" * 20, "Start", "#" * 20)
        print(response.to_curl())
        print("#" * 20, "End", "#" * 20)

Prints this:

# #################### Start ####################
# curl -X POST -H "host: <3rdparty>" -H "accept: */*" -H "accept-encoding: gzip, deflate, zstd" -H "connection: keep-alive" -H "user-agent: python-httpx/0.28.1" -H "authorization: Bearer <token>" -H "content-type: multipart/form-data" -H "content-length: 186" -d '--d21e39e0c438fedf66c71fa2514f0ac5
# Content-Disposition: form-data; name="image_url"
# 
# https://<storage>/logo_3.webp
# --d21e39e0c438fedf66c71fa2514f0ac5--
# ' https://<3rdparty>/endpoint
# #################### End ####################
# Fails with: fastapi.exceptions.HTTPException: 400: error: {"error":{"code":400,"message":"missing form parameter 'image_url'"}}

Now, with the boundary (just switched them in headers dict) explicitly provided in the header. Works fine

# #################### Start ####################
# curl -X POST -H "host: <3rd party>" -H "accept: */*" -H "accept-encoding: gzip, deflate, zstd" -H "connection: keep-alive" -H "user-agent: python-httpx/0.28.1" -H "authorization: Bearer <token>" -H "content-type: multipart/form-data; boundary=WebKitFormBoundary7MA4YWxkTrZu0gW" -H "content-length: 188" -d '--WebKitFormBoundary7MA4YWxkTrZu0gW
# Content-Disposition: form-data; name="image_url"
# 
# https://alxdev.blob.core.windows.net/volvo-v90/logo_3.webp
# --WebKitFormBoundary7MA4YWxkTrZu0gW--
# ' https://<3rdparty>/endpoints
# #################### End ####################

Notice, that in the second case boundary is present in the header, while in the first isn't. I think this is a bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions