bytes.fromhex()
The inverse of bytes.hex. Unlike float.fromhex there is no 0x prefix and no ambiguity — but the digits must come in complete pairs.
Demo
Each pair of hex digits becomes one byte, so 616263 gives b'abc'. Spaces between bytes are skipped, which means output from hex(' ') parses straight back. The two failure cases are worth reading closely, because the reported POSITION differs: "zz" fails at position 0, where the first bad character sits, while "616" fails at position 3 — the index where the missing fourth digit should have been.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| string | str | yes | Hex digits in pairs. ASCII spaces between bytes are skipped. Upper and lower case both work. No 0x prefix is permitted. |
Return value
bytes — The bytes the hex digits represent. Raises ValueError, naming the exact position, for anything that is not a hex digit or a space.
Common patterns
data = bytes.fromhex(text) assert data.hex() == text.replace(' ', '')
PACKET = bytes.fromhex('deadbeef')
key = bytes.fromhex(os.environ['KEY_HEX'])
Examples
Pitfalls
bytes.fromhex('616')
bytes.fromhex('0616')
bytes.fromhex('0x616263')
bytes.fromhex('0x616263'.removeprefix('0x'))
bytes.fromhex('61:62:63')
bytes.fromhex('61:62:63'.replace(':', ''))
fromhex('616263')
bytes.fromhex('616263')
When to use
- Reading back data written with bytes.hex
- Binary literals in tests, where hex beats escapes for readability
- Keys, digests and checksums arriving as text
- Base64 input → base64.b64decode
- Separators other than spaces → strip them first
- The text is really text → encode it instead
Notes
FAQ
Because position 3 is where the missing digit should have been. Python reports where parsing ran out, not where the last good pair ended — which makes the message point at what is absent rather than what is present.
bytes.fromhex('616') # ValueError: ... at position 3