The empty rectangle where an emoji should be has a name — tofu — and it always means exactly one thing. This page explains what that is, walks through the several distinct reasons it happens, and covers two behaviours that surprise people: why Windows will never show you a flag emoji, and why a family emoji sometimes splits into four separate people.
What the box means
It is the .notdef glyph — the placeholder a font draws when asked for a character it has no picture for. Your text is not damaged. The character code is intact and correct; the font simply cannot draw it. The same message will display perfectly on a device with a more complete font.
Tofu, and why it exists
Every font contains a glyph at index 0 called .notdef, which is conventionally an empty or crossed rectangle. When text rendering requests a character the font does not contain, this is what gets drawn.
Displaying something is deliberate. Silently dropping unknown characters would hide the fact that information is missing — you would read a sentence with a word invisibly absent and never know. The box is an honest signal: something is here and this font cannot show it.
The nickname comes from the resemblance to a block of tofu, and it is used seriously enough that Google's pan-Unicode font family is called Noto — short for "no more tofu". Its explicit goal is to cover every character in Unicode so the box never needs to appear.
💡 Boxes with numbers inside are more helpful
Some systems draw the character's hexadecimal code point inside the box instead of leaving it empty. A box reading 1F92F tells you precisely which character is missing, which you can look up. This is standard on Android and in some Linux font stacks, and it turns an unhelpful placeholder into a diagnostic.
The five causes
| Cause | Looks like | Fix |
|---|---|---|
| No emoji font installed | Every emoji is a box | Install Noto Color Emoji |
| Font predates the emoji | Older emoji fine, new ones boxes | Update the operating system |
| Renderer ignores ZWJ | Compound emoji split into parts | Update software; often unfixable on old systems |
| Deliberate non-support | Flags shown as letter pairs | Not fixable — it is by design |
| Encoding damage | Question marks or ð characters | A different problem — see below |
Distinguishing tofu from encoding damage
This distinction matters because the fixes are completely different.
| You see | Meaning | Data intact? |
|---|---|---|
| □ or ▯ | Tofu — font lacks the glyph | Yes |
| Box with hex digits | Tofu, with the code shown | Yes |
| ? | Converted to a lossy encoding | No — permanently lost |
| ð and similar | UTF-8 bytes read as Latin-1 | Yes, recoverable if re-decoded |
| � | Invalid byte sequence | No |
A box is a display problem — copy the text elsewhere and it works. A question mark is a data problem — the character was replaced during a conversion to an encoding that could not represent it, and copying it anywhere gives you a question mark forever.
Why Windows shows flags as letters
Type 🇬🇧 on a Mac and you get a Union Jack. Type the same characters on Windows and you get GB. This is not a bug and no update will change it.
Flag emoji are not single characters. They are pairs of regional indicator symbols — a separate alphabet of 26 letters, A to Z, at code points U+1F1E6 to U+1F1FF. A renderer sees two of them together, reads the pair as an ISO country code, and draws the corresponding flag.
Microsoft's emoji font contains the regional indicator letters but no flag glyphs, so Windows draws the letters. The design is widely understood to sidestep the question of which territories get a flag — a genuinely fraught issue that has caused real problems for other vendors.
⚠️ This affects your product, not just your chat
If your interface uses flag emoji for language pickers or country selectors, roughly half your desktop users see two-letter codes instead of flags. It is not broken — GB is arguably clearer than a small flag — but if the design assumed a visual marker, it does not work there.
Use SVG flag icons if flags matter to the design. They render identically everywhere and let you control exactly which territories appear.
When compound emoji fall apart
Many emoji are not single characters at all. They are sequences joined by an invisible character called the zero-width joiner (U+200D), which instructs the renderer to merge the neighbouring emoji into one glyph.
A renderer that understands the sequence draws one merged image. One that does not draws each component in turn — so the family becomes a man, a woman, a girl and a boy standing in a row, and the astronaut becomes a person followed by a rocket.
This is a graceful degradation by design. The meaning survives even when the combined artwork does not, which is why the ZWJ approach was chosen over allocating a new code point for every possible combination — an approach that would have required thousands of them.
Skin tones work the same way
The five skin tone modifiers are based on the Fitzpatrick dermatological scale. A renderer without support shows the base emoji followed by a small coloured square, which is the modifier drawn as its own character.
Text versus emoji presentation
Some characters existed long before emoji and can be drawn either way. A variation selector decides which:
| Sequence | Renders as |
|---|---|
U+2764 | ❤ — monochrome text heart |
U+2764 U+FE0F | ❤️ — colour emoji heart |
U+2708 | ✈ — text aeroplane |
U+2708 U+FE0F | ✈️ — emoji aeroplane |
U+FE0F requests emoji presentation; U+FE0E requests text presentation. This is why a heart appears black and flat in one application and red and glossy in another — the same base character with a different, invisible selector, or a renderer applying its own default.
Fixing it per platform
| Platform | Emoji font | How to fix |
|---|---|---|
| Windows | Segoe UI Emoji | Windows Update. Flags will still not render. |
| macOS / iOS | Apple Color Emoji | System update — the font is not separately installable |
| Android | Noto Color Emoji | System update; some apps bundle their own via AndroidX Emoji2 |
| Linux | Usually none | Install one — see below |
| Web | Whatever the OS provides | Serve an emoji web font, or use images |
Guaranteeing emoji on a website
Listing the emoji fonts after your generic families is important — the browser uses the first font in the list that contains each character, so text uses your typeface and emoji fall through to the colour font. Putting them first would apply the emoji font to ordinary text where it happens to have glyphs.
Where emoji must be identical for every visitor — in a product interface, or in marketing where the design matters — use SVG images from an open set such as Twemoji rather than font characters. It costs a few requests and removes all platform variation.
🚨 The same emoji means different things on different platforms
Vendors draw emoji themselves, and the results have historically diverged sharply. The grimacing face has read as a smile on one platform and a pained wince on another; the pistol was redrawn as a water pistol by every major vendor at different times, so the same message could be threatening on one device and playful on another.
For anything where tone matters — a support reply, a moderation decision, a legal record — do not assume the recipient sees what you see.
Emoji in databases
A very common cause of emoji turning into question marks has nothing to do with fonts.
MySQL's utf8 character set is not real UTF-8. It stores a maximum of three bytes per character, which covers everything up to U+FFFF and excludes every emoji — those live above U+FFFF and need four bytes. Inserting an emoji into a utf8 column either raises an error or silently truncates the string at that point.
The name is a historical accident that has cost an enormous amount of debugging time: utf8 was defined before four-byte characters were in wide use, and renaming it later would have broken existing schemas. In MySQL 8, utf8mb4 is the default — but plenty of older databases and connection strings still specify the incomplete one.
Summary
- A box means the font lacks the glyph. Your data is intact.
- A question mark means the data is gone — a different and worse problem.
- Windows shows flags as letter pairs by design. No update changes it; use SVG icons if flags matter.
- Compound emoji are joined with an invisible ZWJ and fall back to their components.
- Linux usually needs an emoji font installed — Noto Color Emoji.
- List platform emoji fonts last in your CSS stack.
- MySQL's
utf8cannot store emoji. Useutf8mb4. - The same emoji looks different across platforms. Do not rely on it to carry tone.
Frequently Asked Questions
What does the empty box instead of an emoji mean?
It is the .notdef glyph, nicknamed tofu, and it means the font being used has no drawing for that character. It is not corruption and the text is not damaged — the character code is correct and intact, and it will display normally on a device whose font includes it.
Why does Windows show country flags as two letters instead of a flag?
Windows deliberately does not render flag emoji. Flags are encoded as pairs of regional indicator symbols — 🇬🇧 is really the letters G and B in a special alphabet — and Microsoft chose to display those letters rather than draw flags, a decision widely understood to avoid taking positions on contested territories. The characters are correct; Windows renders them as designed.
Why does a family emoji show as several separate people?
Compound emoji are built by joining several emoji with an invisible zero-width joiner, U+200D. A renderer that understands the sequence draws one combined glyph; one that does not draws each component separately. So the family becomes a man, a woman and two children in a row — every character is present, just not merged.
How do I fix missing emoji on Linux?
Install a colour emoji font — Noto Color Emoji is the standard choice and is packaged for every major distribution. Most desktop Linux installations do not include one by default, which is why emoji appear as boxes or monochrome outlines out of the box.
Why do new emoji not show on my older phone?
Emoji are added to Unicode roughly annually, and support requires a font update, which arrives with an operating system update. A device that no longer receives updates is frozen at whichever emoji set shipped last. Nothing can be installed to fix it on a locked-down mobile OS.