Fix Chinese Boxes and Mojibake in WSL: Windows Terminal Fonts and UTF-8 Locales (2026)

Maintenance note (September 1, 2026): This page now begins with a layered troubleshooting method for current WSL and Windows Terminal. The complete 2019 body remains at the end with only trailing whitespace normalized; its manual locale edit, old Linux font package, and third-party reference are historical records rather than current evidence.

Chinese “boxes” and garbled text can look related, but they usually have different causes:

  • □□□ or hollow squares usually mean the selected terminal font lacks the glyph;
  • text resembling 中文 usually means UTF-8 bytes were decoded using the wrong encoding; and
  • usually means the input contains bytes that the current decoder cannot interpret.

First determine whether the failure is in Windows terminal rendering, the WSL locale, or one file or application’s encoding. Do not change the font, locale, and application settings together: even if the symptom disappears, the actual cause will remain unknown.

1. Record the WSL, terminal, and distribution environment

Record WSL state in PowerShell:

wsl --version
wsl --status
wsl --list --verbose

Old inbox builds of WSL may not support wsl --version; Microsoft’s troubleshooting guidance says to record wsl.exe --status in that case. Also record the Windows version, Windows Terminal version, active Terminal profile, and Ubuntu version. Preserve the reproducible environment before considering an update.

Inside Ubuntu/WSL, run:

printf '中文测试:你好,世界n'
locale
locale charmap
locale -a | sed -n '1,40p'
python3 - <<'PY'
import locale
import sys

print("stdout:", sys.stdout.encoding)
print("preferred:", locale.getpreferredencoding(False))
print("sample:", "中文测试:你好,世界")
PY

If the first line is already boxes while locale charmap says UTF-8, inspect the Windows Terminal font first. If Python reports an encoding error or the charmap is not UTF-8, handle the locale. If only one application or file fails, skip to section 5.

2. Fix boxes: inspect the Windows Terminal profile font

A WSL shell emits characters and control sequences; Windows Terminal draws the terminal cells on screen. Microsoft documents the font as an Appearance setting on each profile. Installing a font inside WSL therefore does not automatically change the font used by Windows Terminal.

In Windows Terminal:

  1. Press Ctrl+, to open Settings.
  2. Select the Ubuntu/WSL profile actually in use.
  3. Open Appearance.
  4. Inspect Font face and choose an installed font verified to contain Simplified Chinese glyphs.
  5. Open a new tab and repeat the Chinese test from the previous section.

Microsoft’s font catalogue identifies Microsoft YaHei as a Simplified Chinese font and lists it as supplied with Windows 10 and Windows 11. First confirm that the font exists under Windows Settings > Personalization > Fonts. If the environment requires a monospaced face, install a trusted CJK monospaced font, verify its coverage, and select its exact family name in the Terminal profile.

When editing JSON, the following is only a fragment to place inside the target profile, not a complete settings.json file:

"font": {
  "face": "Microsoft YaHei",
  "size": 12
}

Microsoft documents the font object for Windows Terminal 1.10 and later; older versions used the legacy fontFace property. For the legacy Console Host from the original Windows 10 era, avoid copying registry-font workarounds. Prefer current Windows Terminal on a supported Windows 10 22H2 or Windows 11 installation.

If ordinary Chinese works and only prompt icons are boxes, the locale is not the problem. The selected font lacks the private or specialised glyphs used by that prompt. Choose a font matching the prompt or use a theme that does not require those icons.

3. Fix encoding: Chinese display does not require a Chinese locale

Chinese display requires a consistent Unicode/UTF-8 path plus a font containing the glyphs; it does not require LANG=zh_CN.UTF-8. C.UTF-8, en_US.UTF-8, and other UTF-8 locales can all carry Chinese. Selecting a Chinese locale also changes program messages, dates, sorting, and other locale-sensitive behaviour.

If locale charmap already returns UTF-8, do not edit /etc/default/locale solely to address boxes. If the charmap is not UTF-8, first consider a UTF-8 locale that does not change the interface language:

sudo update-locale LANG=C.UTF-8 LANGUAGE

If Simplified Chinese program messages are genuinely wanted, generate the locale and use Ubuntu’s validating tool to write the global setting:

sudo apt update
sudo apt install --yes locales
sudo locale-gen zh_CN.UTF-8
sudo update-locale LANG=zh_CN.UTF-8 LANGUAGE=zh_CN:zh

Do not persistently set LC_ALL to hide conflicts; it overrides the individual LC_* categories. update-locale checks values and updates the locale configuration, avoiding smart quotes and other errors introduced by manual editing.

Verify a locale change only in a new WSL session. After saving any running work, PowerShell can stop all WSL instances before the distribution is reopened:

wsl --shutdown

This terminates every running WSL distribution and process, so save first. After reopening, rerun locale charmap and the Chinese test.

4. Do not confuse Windows fonts with Linux fonts

An ordinary Windows Terminal tab uses Windows fonts. The ttf-wqy-microhei package installed by the 2019 body is a Linux package and normally does not repair the font selected by Windows Terminal.

Linux fonts matter for:

  • Linux GUI applications running through WSLg;
  • Linux programs that render PDFs, images, or other output inside WSL; and
  • a Linux-side renderer that explicitly selects fonts through fontconfig.

For those cases, inspect fontconfig before installing anything:

fc-match 'sans-serif:lang=zh-cn'
fc-list :lang=zh-cn family | sed -n '1,20p'

If the target Ubuntu release has no suitable CJK font, use a distribution package rather than an untrusted download:

sudo apt update
sudo apt install --yes fontconfig fonts-noto-cjk
fc-cache -f

Restart the affected Linux GUI or renderer afterward. Do not treat this as the default repair for boxes in Windows Terminal.

5. If only one file or program is garbled, inspect its encoding

If the test string works but an old log, CSV, or source file does not, the system font and global locale are probably fine. Preserve the original and confirm the encoding declared by its producer. Do not visually guess between GBK, GB18030, Big5, and UTF-8 and then overwrite the source.

Inspect bytes without modifying the file:

python3 - <<'PY'
from pathlib import Path

path = Path("sample.txt")
data = path.read_bytes()
print("first bytes:", data[:32].hex(" "))
print("UTF-8 preview:", data.decode("utf-8"))
PY

If UTF-8 decoding fails, the error offset is evidence—not a reason to change the global locale immediately. Check the generating program, protocol, or export settings. Once the source encoding is known, convert into a new file and compare the result. For example, only after confirming that the source is GB18030:

iconv -f GB18030 -t UTF-8 legacy.txt > converted-utf8.txt

Do not overwrite legacy.txt until the result, line count, and business content have been verified.

6. Use a minimal reproduction to locate the boundary

Use these results to choose the next action:

ResultLikely boundaryNext action
Chinese is boxes in both PowerShell and WSLWindows Terminal profile/fontInspect the active profile’s Font face and Windows font installation
PowerShell works, but WSL’s UTF-8 test is boxesThe WSL profile may override the font, or it uses a different terminal hostConfirm the profile and host for that tab
UTF-8 test works; one file is garbledFile or application encodingPreserve the original, confirm the producer’s encoding, and convert a copy
locale charmap is not UTF-8WSL localeUse update-locale with an installed UTF-8 locale, then restart WSL
Ordinary Chinese works; only prompt icons are boxesSpecial glyphs are absentChoose a font matching the theme or simplify the prompt
Windows Terminal works; a WSLg application has boxesLinux fontconfig/GUI fontInspect fc-match and install CJK fonts through the distribution if needed

7. Verify and roll back

Retest immediately after each individual change:

printf '中文测试:你好,世界n'
locale charmap
python3 -c 'print("Python 中文测试")'

Verify that:

  • a new Windows Terminal tab uses the intended WSL profile and font;
  • locale charmap reports UTF-8;
  • the shell, Python, and the affected application display the same test text;
  • English and Chinese filenames plus copy/paste have not gained new corruption;
  • WSLg font packages were installed only for an actual Linux-rendering need; and
  • the prior Terminal setting and locale values were recorded and can be restored individually.

What changed from the 2019 body

2019 content2026 maintained treatment
Edit /etc/default/locale directlyInspect the charmap first; use validating update-locale when a change is required
Tie Chinese display to zh_CN.UTF-8Explain that any suitable UTF-8 locale can carry Chinese; interface language is a separate choice
Install ttf-wqy-microhei as a general repairSeparate Windows Terminal fonts from WSLg/Linux fontconfig fonts
No distinction between boxes and garbled textLocate missing glyphs, wrong decoding, and invalid bytes separately
Target the 2019 Windows 10 legacy hostMaintain for current WSL and Windows Terminal while preserving the historical context
Use a third-party article as the only referenceUse Microsoft, Ubuntu, and relevant official documentation; retain the old link only in the archive

Authoritative references

Windows, WSL, Ubuntu, and Terminal defaults will continue to change. Consult the help and official documentation for the versions installed on the target machine.

Complete 2019 body (source archive; do not execute)


sudo vim /etc/default/locale

 LANG=zh_CN.UTF-8
 LANGUAGE=”zh_CN:zh”

 sudo apt-get install ttf-wqy-microhei

[https://blog.csdn.net/sethqqq/article/details/77017759](https://blog.csdn.net/sethqqq/article/details/77017759)

Leave a Reply