[Django] #36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is invalid

4 views
Skip to first unread message

Django

unread,
Feb 15, 2026, 10:18:52 PMFeb 15
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Type: Bug
Status: new | Component: HTTP
| handling
Version: 6.0 | Severity: Normal
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
When a multipart form upload includes an RFC 2231 encoded `filename*`
parameter with an invalid encoding name (e.g.,
`filename*=BOGUS''test%20file.txt`),
[parse_header_parameters()](https://github.com/django/django/blob/main/django/utils/http.py#L332),
[django/utils/http.py](https://github.com/django/django/blob/main/django/utils/http.py)
passes the encoding to `urllib.parse.unquote()`, which raises
`LookupError`.

The caller in
[django/http/multipartparser.py](https://github.com/django/django/blob/main/django/http/multipartparser.py#L729)
only catches `ValueError`:

{{{#!python
except ValueError: # Invalid header.
continue
}}}

Since `LookupError` is not a subclass of `ValueError`, the exception
propagates and results in a 500 Internal Server Error.


== Steps to Reproduce ==
1. Create a simple upload view:
{{{#!python
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload(request):
if request.method == "POST" and request.FILES:
return JsonResponse({"filename": request.FILES["file"].name})
return JsonResponse({"error": "No file"}, status=400)
}}}
2. Send a multipart request with a bogus encoding:
{{{#!python
import http.client
boundary = "----PoC"
body = (
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"file\"; "
f"filename*=BOGUS''test%20file.txt\r\n"
f"Content-Type: application/octet-stream\r\n"
f"\r\n"
f"content\r\n"
f"--{boundary}--\r\n"
)
conn = http.client.HTTPConnection("localhost", 8000)
conn.request("POST", "/upload/", body=body.encode(),
headers={"Content-Type": f"multipart/form-data; boundary={boundary}"})
print(conn.getresponse().status) # Returns 500
}}}

The filename must contain at least one percent-encoded character (e.g.,
`%20`) for `unquote()` to invoke the codec.

Confirmed on Django 6.0.2, Python 3.14.
--
Ticket URL: <https://code.djangoproject.com/ticket/36931>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Feb 15, 2026, 10:36:51 PMFeb 15
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by sammiee5311:

Old description:
New description:
PR link: https://github.com/django/django/pull/20714

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:1>

Django

unread,
Feb 16, 2026, 3:34:21 AMFeb 16
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by sammiee5311):

PR: https://github.com/django/django/pull/20714

All tests pass (requests_tests — 115 tests) under SQLite, Python 3.14,
macOS.
--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:2>

Django

unread,
Feb 16, 2026, 2:01:52 PMFeb 16
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner: Huwaiza
Type: Bug | Status: assigned
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Huwaiza):

* owner: (none) => Huwaiza
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:3>

Django

unread,
Feb 16, 2026, 3:18:25 PMFeb 16
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Huwaiza):

* owner: Huwaiza => (none)
* status: assigned => new

--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:4>

Django

unread,
Feb 16, 2026, 8:58:40 PMFeb 16
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner: (none)
Type: Bug | Status: new
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
> PR link: https://github.com/django/django/pull/20714

New description:

When a multipart form upload includes an RFC 2231 encoded `filename*`
parameter with an invalid encoding name (e.g.,
`filename*=BOGUS''test%20file.txt`),
[[https://github.com/django/django/blob/main/django/utils/http.py#L332|parse_header_parameters()]],
[[https://github.com/django/django/blob/main/django/utils/http.py|django/utils/http.py]]
passes the encoding to `urllib.parse.unquote()`, which raises
`LookupError`.

The caller in
[[https://github.com/django/django/blob/main/django/http/multipartparser.py#L729|django/http/multipartparser.py]]
--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:5>

Django

unread,
Feb 16, 2026, 9:03:51 PMFeb 16
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner:
| sammiee5311
Type: Bug | Status: assigned
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage:
LookupError RFC2231 | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by sammiee5311):

* owner: (none) => sammiee5311
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:6>

Django

unread,
Feb 20, 2026, 5:36:01 PMFeb 20
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner:
Type: | sammiee5311
Cleanup/optimization | Status: assigned
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage: Accepted
LookupError RFC2231 |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* stage: Unreviewed => Accepted
* type: Bug => Cleanup/optimization

Comment:

[https://github.com/django/django/pull/20714 PR]
--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:7>

Django

unread,
Feb 20, 2026, 5:36:14 PMFeb 20
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner:
Type: | sammiee5311
Cleanup/optimization | Status: assigned
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage: Accepted
LookupError RFC2231 |
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:8>

Django

unread,
Feb 24, 2026, 1:42:29 PM (11 days ago) Feb 24
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner:
Type: | sammiee5311
Cleanup/optimization | Status: assigned
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution:
Keywords: multipart parser | Triage Stage: Ready for
LookupError RFC2231 | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin

--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:9>

Django

unread,
Feb 24, 2026, 1:44:56 PM (11 days ago) Feb 24
to django-...@googlegroups.com
#36931: Unhandled LookupError in multipart parser when RFC 2231 encoding name is
invalid
-------------------------------------+-------------------------------------
Reporter: sammiee5311 | Owner:
Type: | sammiee5311
Cleanup/optimization | Status: closed
Component: HTTP handling | Version: 6.0
Severity: Normal | Resolution: fixed
Keywords: multipart parser | Triage Stage: Ready for
LookupError RFC2231 | checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls <jacobtylerwalls@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"e84dc8715e91d51364ba6bda2b2fb07e7a8b750e" e84dc871]:
{{{#!CommitTicketReference repository=""
revision="e84dc8715e91d51364ba6bda2b2fb07e7a8b750e"
Fixed #36931 -- Handled LookupError in multipart parser for invalid RFC
2231 encoding.

Added LookupError to the except clause so invalid headers are silently
skipped, consistent with other malformed header handling.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36931#comment:10>
Reply all
Reply to author
Forward
0 new messages