How to Decode Base64 in Python — Step by Step

Decoding Base64 in Python looks trivial until you hit a padding error or end up with mojibake instead of readable text. This tutorial walks through the correct pattern step by step, including how to handle malformed input and when to stop at bytes instead of decoding to a string.

Step 1: Import the base64 module

No installation needed — base64 is part of the Python standard library.

import base64

Step 2: Decode to bytes with b64decode

base64.b64decode() accepts either a str or bytes input and always returns bytes. This is the one function you need for the actual decoding step.

encoded = "SGVsbG8sIFdvcmxkIQ=="

raw_bytes = base64.b64decode(encoded)
print(raw_bytes)
# → b'Hello, World!'

Step 3: Convert bytes to text (only if it's text)

If the original data was a string, call .decode("utf-8") on the bytes to get readable text back. If the original data was binary (an image, a PDF, a zip file), skip this step and write the bytes straight to a file instead.

# Text data
text = raw_bytes.decode("utf-8")
print(text)
# → Hello, World!

# Binary data — write directly, do NOT call .decode()
with open("output.png", "wb") as f:
    f.write(raw_bytes)

Handling the "Incorrect padding" error

Base64 requires the encoded string's length to be a multiple of 4, with = used to pad the final group. If you receive a Base64 string from an API or a JWT segment with padding stripped, b64decode raises binascii.Error. Pad it back manually before decoding:

import base64

def safe_b64decode(s: str) -> bytes:
    # Add back any missing '=' padding
    padding_needed = -len(s) % 4
    s += "=" * padding_needed
    return base64.b64decode(s)

# Works even if padding was stripped (common in JWTs)
safe_b64decode("SGVsbG8")
# → b'Hello'

Validating Base64 before decoding

Use the validate=True flag to make Python reject strings containing characters outside the Base64 alphabet, instead of silently ignoring them.

import base64
import binascii

def try_decode(s: str):
    try:
        return base64.b64decode(s, validate=True)
    except (binascii.Error, ValueError) as e:
        print(f"Invalid Base64: {e}")
        return None

try_decode("not valid base64!!")  # → prints error, returns None
try_decode("SGVsbG8=")            # → b'Hello'

Common pitfalls checklist

  • Decoding a URL-safe Base64 string with b64decode instead of urlsafe_b64decode — the - and _ characters won't decode correctly.
  • Calling .decode("utf-8") on binary output like image bytes — this raises UnicodeDecodeError.
  • Forgetting that Base64 strings from web APIs sometimes have whitespace or newlines injected — strip them first with s.strip().
  • Assuming decoding proves the data is safe — Base64 is not encryption; always validate/sanitize decoded content before using it.

Frequently Asked Questions

How do I decode a Base64 string in Python?

Use base64.b64decode(your_string) to get the raw bytes, then call .decode("utf-8") on the result if the original data was text. If the Base64 string is a plain str, Python automatically encodes it to bytes before decoding.

Why do I get "Incorrect padding" when decoding Base64 in Python?

Base64 strings must have a length that is a multiple of 4, using = as padding. This error means the input was truncated or padding was stripped. Fix it by appending the missing = characters before calling b64decode.

Should I decode Base64 to bytes or to a string in Python?

Decode to bytes first with b64decode() always. Only call .decode("utf-8") afterward if you know the original data was text, such as JSON or plain strings. For images, PDFs, or other binary files, keep the result as bytes and write it directly to a file.

Try the Free Base64 Encoder/Decoder

Need a quick decode without writing a script? Paste your Base64 string into our free online tool and get instant results — right in your browser.

Related articles