You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Change default encoding to utf-8 in normalize_header_key and normalize_header_value functions #3238
I have encountered decoding errors with some requests that use ASCII encoding. Changing the default encoding to UTF-8 resolves these errors. I propose updating the normalize_header_key and normalize_header_value functions in _utils.py to use UTF-8 as the default encoding.
Steps to Reproduce
Call normalize_header_key or normalize_header_value with a non-ASCII string and no encoding specified.
Observe the decoding failure with ASCII encoding.
Change the encoding to UTF-8 and observe that the error is resolved.
Example Code
header_key_unicode="内容类型"normalized_key_unicode=normalize_header_key(header_key_unicode, lower=True)
# This raises a UnicodeEncodeError with ASCII encoding.normalized_key_unicode_utf8=normalize_header_key(header_key_unicode, lower=True, encoding="utf-8")
print(normalized_key_unicode_utf8) # Works correctly with UTF-8 encoding.
Proposed Solution
Modify the _utils.py file to use UTF-8 as the default encoding:
Using UTF-8 as the default encoding ensures that the functions can handle a wider range of input values without raising an error. UTF-8 encoding is capable of encoding a larger set of characters compared to ASCII.
hey guys, can I work on this?
Thank you for your interest in this issue! I am currently working on a Pull Request to address this problem. If you have any suggestions or would like to review the changes, your input would be greatly appreciated.
Heya, thanks for the consideration... I think this may be valid, tho could you re-frame it so that you're describing the issue against public API. For example describe this using httpx.Headers(...). We can then unpick exactly what should and should not be valid.
Edit: Okay, I see PR #3241 now. We don't want to support utf-8 in header keys which have a constrained set of allowed characters. I do think it's a sensible default for header values tho.
In the example code, the Referer field contains the Japanese word テスト, which will raise an error and interrupt the request.
The same issue can occur in responses. If the server's response does not specify the encoding, httpx will use ASCII encoding to decode テスト, resulting in an error.
Therefore, I suggest changing the default encoding from ASCII to UTF-8 to better handle such cases.
@ZM25XC UTF-8 is not accepted in headers. You can only use ISO-8859-1 in HTTP headers according to rfc.
If you want to put utf8 characters in the url and pass it to referer, you should url encode all utf8 characters first. In fact, this is how this url actually is.
from httpx import Response
x = Response(status_code=200, headers={"x-ratelimit-reset-requests": "59.999µs"})
print(x.headers)
Results the below error.
Traceback (most recent call last):
File "/Users/user/development/httpx/demo.py", line 10, in <module>
x = Response(status_code=200, headers={"x-ratelimit-reset-requests": "59.999µs"})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/development/httpx/httpx/_models.py", line 532, in __init__
self.headers = Headers(headers)
^^^^^^^^^^^^^^^^
File "/Users/user/development/httpx/httpx/_models.py", line 156, in __init__
bytes_value = _normalize_header_value(v, encoding)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/development/httpx/httpx/_models.py", line 82, in _normalize_header_value
return value.encode(encoding or "ascii")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode character '\xb5' in position 6: ordinal not in range(128)
I suppose this is because self.headers = Headers(headers) is called during __init__ and the default_encoding is not passed?
For header values, perhaps it should default to iso-8859-1 or utf-8.
The behaviour for header encoding/decoding outside of the ascii range isn't defined, so the safest approach is to keep to strict ascii, with URL quoting if required. (Eg. #3238 (comment))
The behaviour for header encoding/decoding outside of the ascii range isn't defined, so the safest approach is to keep to strict ascii, with URL quoting if required. (Eg. #3238 (comment))
I understand this is for security reasons, but some developers' responses have headers that are returned in an irregular format. When we use httpx to make requests, we can't manually encode them. Could you add a parameter to allow us to specify the parsing encoding?
When using httpx to actively send requests, we can manually encode and handle the headers, but we cannot pre-encode and handle the hesders of the request response. Most errors occur when parsing the headers of the response
we can manually encode and handle the headers, but we cannot pre-encode and handle the hesders of the request response.
Correct yep.
Using iso-8859-1 would be robust to servers returning headers including obs-text byte ranges %x80-FF. RFC-9110 indicates that clients should allow these byte ranges and treat them as "opaque data" ie. no defined encoding.
As a useful data point, do you have an example URL that's returning headers with these values?
I don't have a public URL that returns headers with these values, but the example I cited above is based on headers in the OpenAI API spec, where it is possible that some responses have non-ascii characters in header values "x-ratelimit-reset-requests": "90µs"
Activity
iamjatinyadav commentedon Jul 13, 2024
hey guys, can I work on this?
SonderZhong commentedon Jul 14, 2024
lovelydinosaur commentedon Jul 23, 2024
Heya, thanks for the consideration... I think this may be valid, tho could you re-frame it so that you're describing the issue against public API. For example describe this using
httpx.Headers(...). We can then unpick exactly what should and should not be valid.Edit: Okay, I see PR #3241 now. We don't want to support utf-8 in header keys which have a constrained set of allowed characters. I do think it's a sensible default for header values tho.
SonderZhong commentedon Jul 24, 2024
In a request, if the headers contain non-ASCII characters and the encoding is not specified, an error will be raised. For example:

In the example code, the Referer field contains the Japanese word テスト, which will raise an error and interrupt the request.
The same issue can occur in responses. If the server's response does not specify the encoding, httpx will use ASCII encoding to decode テスト, resulting in an error.
Therefore, I suggest changing the default encoding from ASCII to UTF-8 to better handle such cases.

Cycloctane commentedon Sep 26, 2024
@ZM25XC UTF-8 is not accepted in headers. You can only use ISO-8859-1 in HTTP headers according to rfc.
If you want to put utf8 characters in the url and pass it to referer, you should url encode all utf8 characters first. In fact, this is how this url actually is.
andrewtlw commentedon Sep 11, 2025
hello @lovelydinosaur, if not
utf-8in the headers, would it make sense to default toiso8859-1instead? I am also facing the same issue as the OPlovelydinosaur commentedon Sep 11, 2025
Could you be more specific?
andrewtlw commentedon Sep 11, 2025
Sure.
Results the below error.
I suppose this is because
self.headers = Headers(headers)is called during__init__and the default_encoding is not passed?For header values, perhaps it should default to
iso-8859-1orutf-8.lovelydinosaur commentedon Sep 11, 2025
The behaviour for header encoding/decoding outside of the ascii range isn't defined, so the safest approach is to keep to strict ascii, with URL quoting if required. (Eg. #3238 (comment))
SonderZhong commentedon Sep 11, 2025
SonderZhong commentedon Sep 11, 2025
When using httpx to actively send requests, we can manually encode and handle the headers, but we cannot pre-encode and handle the hesders of the request response. Most errors occur when parsing the headers of the response
lovelydinosaur commentedon Sep 11, 2025
Correct yep.
Using
iso-8859-1would be robust to servers returning headers includingobs-textbyte ranges%x80-FF. RFC-9110 indicates that clients should allow these byte ranges and treat them as "opaque data" ie. no defined encoding.As a useful data point, do you have an example URL that's returning headers with these values?
andrewtlw commentedon Sep 12, 2025
I don't have a public URL that returns headers with these values, but the example I cited above is based on headers in the OpenAI API spec, where it is possible that some responses have non-ascii characters in header values
"x-ratelimit-reset-requests": "90µs"