Base64 encode/decode · Guide

Base64 to Text Python: Decoding With the base64 Module

Python's `base64` module is strict about the difference between bytes and text, which makes it slightly more verbose than other languages and considerably harder to get subtly wrong.

The bytes boundary

b64decode returns bytes, always. Turning those into a string is a separate decision, and Python makes you state it:

Python
import base64

raw  = base64.b64decode('aGVsbG8=')   # b'hello'
text = raw.decode('utf-8')            # 'hello'

# encoding, the other direction
base64.b64encode('hello'.encode('utf-8')).decode('ascii')

The final .decode("ascii") on encode is safe because Base64 output is always ASCII. The .decode("utf-8") on the way back is the one that can fail, and it should — it means the bytes were not UTF-8 text.

Padding errors

binascii.Error: Incorrect padding means the length is not a multiple of 4. Strings copied from JSON, logs or URLs frequently lose their =:

Python
def decode_padded(s: str) -> bytes:
    return base64.b64decode(s + '=' * (-len(s) % 4))

validate=False is the default and silently ignores characters outside the alphabet. Pass validate=True when you want malformed input to raise rather than decode into something unexpected.

URL-safe variants and binary

JWTs and URL parameters use - and _ in place of + and /. Use the dedicated functions rather than string replacement:

Python
base64.urlsafe_b64decode(token_part + '==')
base64.urlsafe_b64encode(data).rstrip(b'=')

And if the payload is not text, do not call .decode() at all — write the bytes to a file in binary mode. Checking the first bytes tells you which case you are in: b"%PDF", b"\x89PNG", b"PK".

Frequently asked questions

Why does b64decode reject my string?

Missing padding, or characters outside the alphabet. Pad to a multiple of 4, or use urlsafe_b64decode for token strings.

Why does .decode() raise UnicodeDecodeError?

The decoded bytes are not UTF-8 text — most likely binary data such as an image or archive.

Can b64encode take a str?

No. Call .encode() first, choosing the character encoding explicitly.

Ready to try it?

Open the free browser-based Base64 encode/decode and apply what you just read — no sign-up, runs locally.

Open the Base64 encode/decode tool