MailDingo

Read the fields

Encoded-words (=?UTF-8?B?…?=)

Strings like =?UTF-8?B?…?= are RFC 2047 encoded-words: a way to carry non-ASCII text in headers. Easy to decode, and sometimes used to hide text from filters.

5 min read · updated 2026-10-26 · 7 RFC sections cited

A header value like =?UTF-8?B?Q2Fmw6k=?= is an encoded-word, defined in RFC 2047. It's how email squeezes accented letters, non-Latin scripts and emoji into headers that were originally limited to plain ASCII. Your mail app decodes it silently and shows Café. The format is always =?charset?encoding?text?=, where the encoding is B (Base64) or Q (a quoted-printable variant). Seeing encoded-words is completely normal. They only matter for safety when someone uses them to hide plain English from a spam filter or to smuggle a fake address into a display name.

The format, piece by piece

RFC 2047 §2 defines the structure:

Subject: =?UTF-8?B?Q2Fmw6k=?=
           ^^^^^ ^ ^^^^^^^^
           |     | encoded text
           |     encoding: B or Q (either case)
           character set
  • =? and ?= mark the start and end.
  • Charset: the character set of the decoded bytes. Today it's almost always UTF-8. Older mail uses ISO-8859-1 (Western European), windows-1252, ISO-2022-JP, KOI8-R, GB2312 and others. Case doesn't matter.
  • Encoding: B or Q (also case-insensitive).
  • Text: the encoded bytes, with no spaces allowed inside.

One encoded-word may be at most 75 characters, so long subjects are split into several, one after another on folded lines. When a mail app displays them, it ignores whitespace between adjacent encoded-words and joins them (RFC 2047 §6.2). That's why a subject split across three encoded-words displays as one unbroken sentence.

B encoding: Base64

B is plain Base64, the same scheme used for attachments (RFC 2047 §4.1). It's used when most of the text isn't ASCII, and it makes the text unreadable at a glance:

Subject: =?UTF-8?B?WW91ciBpbnZvaWNlIGlzIHJlYWR5?=

To decode by hand, take the part between the third ? and the closing ?= (WW91ciBpbnZvaWNlIGlzIHJlYWR5), Base64-decode it, then read the bytes in the stated charset. The result is Your invoice is ready. Any Base64 decoder works, for example echo 'WW91ciBpbnZvaWNlIGlzIHJlYWR5' | base64 -d on Linux or macOS. A trailing = or == is normal Base64 padding.

Q encoding: mostly readable

Q is designed so mostly-ASCII text stays legible (RFC 2047 §4.2). The rules:

  • Ordinary letters and digits stand for themselves.
  • _ (underscore) means a space.
  • = followed by two hex digits is one byte with that value.

Worked example:

Subject: =?UTF-8?Q?Caf=C3=A9_menu?=

Caf stays as is. =C3=A9 is the two bytes C3 A9, which in UTF-8 are the single character é. _ is a space. menu stays. Result: Café menu.

The same word in an older charset uses fewer bytes, because ISO-8859-1 stores é as a single byte, E9:

Subject: =?ISO-8859-1?Q?Caf=E9_menu?=

This is why the charset label matters. Decoding =E9 as UTF-8 would give you garbage, and that's the cause of the familiar Café mojibake when software guesses the charset wrong.

Where encoded-words may appear

RFC 2047 §5 limits them to:

  • Unstructured text fields such as Subject and Comments, plus extension and X- headers.
  • Display names in address fields (From, To, Cc): the "phrase" part before <address>.
  • Comments in parentheses inside structured fields.

They must not appear in the address itself (the user@domain part), inside a quoted string, or in a Received header. An encoded-word in one of those places isn't valid. Most clients will show it as literal text, but behavior varies.

Why phishers use them

Encoded-words are a legitimate standard, but they're also a cheap way to make text invisible to naive filters and to people skimming raw headers:

Hiding keywords from filters. A filter that searches raw headers for "invoice", "password" or "wire transfer" won't find them inside Base64. Modern filters decode headers before scanning, so this mostly beats homemade rules and simple gateway filters. Still, an all-ASCII English subject sent as B-encoded UTF-8 is a weak signal worth noticing, especially from a sender that otherwise looks hand-built. Many legitimate senders, however, encode everything by default, so this is not proof of anything.

Faking an address in the display name. This is the more dangerous trick:

From: =?UTF-8?B?QWNjb3VudCBTZWN1cml0eSA8c2VjdXJpdHlAYmFuay5leGFtcGxlPg==?= <alerts@mailer.example.net>

The encoded part decodes to Account Security <security@bank.example>. A mail app shows the decoded display name, so the reader sees what looks like a bank address, while the real sending address, the one that SPF, DKIM and DMARC actually check, is alerts@mailer.example.net. RFC 2047 §6.2 itself warns that decoding happens after parsing, so characters like <, > and @ hidden in an encoded-word can look identical to real address syntax once displayed. See display-name spoofing for the wider pattern.

Look-alike characters. An encoded display name or subject can contain Cyrillic or Greek letters that look like Latin ones, or invisible characters such as zero-width spaces. Decoded, it reads like a familiar brand name; byte for byte, it's a different string. The look-alike domains guide covers this for domain names.

Tip: When a display name decodes to something containing @ or angle brackets, ignore it and look at the actual address in <…> at the end of the From line. The analyser decodes encoded-words for you and flags display names that contain a different address.

Raw UTF-8 headers (RFC 6532)

Encoded-words are a workaround from 1996. RFC 6532, part of the internationalized email (EAI) standards, allows headers to contain raw UTF-8 directly: in subjects, display names, and even in the address and domain themselves (RFC 6532 §3.2). Header field names must still be ASCII.

On mail sent this way you'll see readable non-ASCII text straight in the raw header, not =?…?= sequences. RFC 6532 §3.6 says software producing such messages should not use encoded-words at all, though in practice you'll still see a mix: many senders keep encoding for compatibility, since a message can't use raw UTF-8 headers unless every server along the route supports the SMTPUTF8 extension.

Raw UTF-8 makes look-alike tricks easier to spot when you can read the script and harder when you can't. The same advice applies: compare the address the authentication results refer to, not what the display name says.

Quick decoding checklist

  1. Find each =?charset?X?text?= group. Adjacent groups join with no space between them.
  2. B: Base64-decode the text. Q: turn _ into a space and =XX into byte XX.
  3. Interpret the bytes using the charset given.
  4. Ask whether the decoded text claims an identity (a name, a brand, an address) that the real sending address doesn't support. Then check Authentication-Results for that real address, and see spotting phishing from headers for the other signals worth combining.

Got a suspicious email?

Paste its headers into the analyser. It runs on your device and explains every result on this page.

Open the analyser

Next in Read the fields: The Return-Path header →