Python LinuxWindowsmacOS

Python: UnicodeDecodeError: utf-8 codec can't decode byte

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

UnicodeDecodeError «utf-8 codec can't decode byte» возникает, когда файл не в UTF-8: чаще всего cp1251, бинарные данные или BOM. Укажите кодировку в open(), используйте errors="replace" или определите её через chardet.

В этой статье
  1. Что означает ошибка
  2. Причины и решения
  3. Пошаговое решение
  4. Примеры кода

#Что означает ошибка

Сообщение
UnicodeDecodeError

Python пытается прочитать байты как текст в UTF-8, а они на самом деле записаны в другой кодировке (чаще всего cp1251 для русских файлов из Windows, cp866 из консоли DOS, utf-16 из Excel/PowerShell) либо вообще не являются текстом (картинки, архивы, Excel). Число после byte (0xd0, 0xff, 0x98) намекает на тип проблемы: 0xff 0xfe — BOM UTF-16.

#Причины и решения

Возможная причинаКак узнатьЧто делать
Кодировка cp1251Файл создан в Windows-программе.Байты 0xc0–0xff в тексте.Откройте с encoding='cp1251'.
Бинарный файлЧитается как текст файл .xlsx, .png, .zip.Ошибка на первом же байте (0x89, 0x50).Откройте в 'rb' и используйте нужную библиотеку.
BOMФайл начинается с маркера UTF-8/UTF-16.Ошибка на 0xff или лишние символы \ufeff.encoding='utf-8-sig' или utf-16.
Битые данныеФайл повреждён или обрезан.Ошибка на середине файла.Используйте errors='replace'.

#Пошаговое решение

  1. Прочитайте текст ошибкиПрочитайте ошибку до конца и запишите имя файла, позицию position N и байт (0xc0 и т. п.). Это означает, что выбранный декодер UTF-8 не смог интерпретировать байты; само по себе это не доказывает Windows-1251. Сделайте копию исходного файла, прежде чем пробовать перекодировку. В VS Code откройте файл через «Файл → Открыть файл», в строке состояния справа внизу посмотрите используемую кодировку и при необходимости выберите «Повторно открыть с кодировкой». Не сохраняйте файл с новой кодировкой, пока не убедились, что текст читается нормально.
  2. Определите кодировкуЕсли происхождение файла известно, сначала выясните кодировку у отправителя или в документации источника: CSV из старой Windows может быть CP1251, но возможны KOI8-R, UTF-16 и другие варианты. Linux: команда file -bi data.txt даёт предположение о типе данных, не безусловно достоверную кодировку. Библиотека chardet по выборке тоже даёт лишь оценку: можно создать отдельное виртуальное окружение и использовать её только как подсказку. Сравните несколько русских фраз с ожидаемыми значениями; если пробная расшифровка даёт «кракозябры», вернитесь к копии.
  3. Укажите кодировку явноЕсли подтверждена кодировка исходного текста, в строке чтения файла в Python укажите её явно: например, with open('data.txt', 'r', encoding='cp1251') as f: и затем читайте из f. Путь замените путём реального файла, а cp1251 — подтверждённой кодировкой. Для UTF-8 с подписью BOM подходит utf-8-sig, для обычного UTF-8 — utf-8. Сохраните изменённый скрипт и запустите прежнюю команду: ошибка должна исчезнуть, а кириллица отображаться без подмены букв; при иной ошибке проверьте, что читается тот же файл.
  4. Не читайте бинарные файлы как текстЕсли файл на самом деле бинарный (.xlsx, изображение, архив, .pdf), не открывайте его в текстовом режиме. Откройте свойства или проверьте расширение и первые байты на копии, затем используйте специализированную библиотеку: openpyxl для XLSX, zipfile для ZIP и т. п. Для просмотра сырых данных в Python используйте open('data.bin', 'rb'), где чтение возвращает байты. Если даже специализированный инструмент сообщает о повреждении структуры, уточните формат у автора или запросите исправленный файл — подбирать текстовую кодировку бессмысленно.
  5. Обработайте повреждённые данныеПри единичных повреждённых байтах и необходимости получить приблизительный текст разрешается errors='replace': неверные последовательности превращаются в символ замены �. Применяйте это только для просмотра/поиска, когда потеря части текста допустима; errors='ignore' незаметно удаляет символы и опасен для документов, идентификаторов, финансовых данных. Сначала подсчитайте количество замен и сохраните оригинал. Если требуется точная миграция, остановитесь и получите корректную копию или выясните настоящую кодировку.
  6. Установите UTF-8 по умолчаниюНе применяйте chcp 65001 и PYTHONUTF8=1 как способ починить файл в CP1251: они влияют на консоль и выбор кодировок по умолчанию, но не преобразуют байты источника. Если программа неправильно использует системную кодировку, укажите encoding= в конкретном вызове чтения/записи и проверьте обе стороны обмена. В Windows PowerShell можно выполнить python -X utf8 script.py для диагностики поведения по умолчанию, но ошибка при чтении действительно не-UTF-8 файла останется. Не меняйте общесистемную локаль из-за одного CSV.
  7. Перекодируйте файлЕсли нужно создать новую UTF-8-копию из подтверждённого CP1251, в терминале Linux/macOS выполните iconv -f CP1251 -t UTF-8 data.txt > data-utf8.txt. Команда создаст отдельный файл и оставит исходный без изменений. Проверьте созданный текст в редакторе и сравните число строк; если iconv сообщает о недопустимой последовательности, не используйте опцию молчаливого пропуска символов. В Windows аналогичное преобразование выполните через «Сохранить с кодировкой» редактора, не перезаписывая исходный файл до проверки.

#Примеры кода

read_file.py
Чтение файла с разными кодировками и автоопределением.
import chardet

with open('data.txt', 'rb') as f:
    raw = f.read()
enc = chardet.detect(raw)['encoding']
print('Кодировка:', enc)
text = raw.decode(enc or 'utf-8', errors='replace')

# Явно указанная кодировка
with open('data.csv', encoding='cp1251', newline='') as f:
    rows = f.read().splitlines()
Linux · Терминал (Bash)Команда
Команды относятся к Linux/macOS; названия файлов замените реальными. Исходный data.txt не изменяется; проверьте data-utf8.txt перед использованием.
# Linux/macOS: оценка типа данных, затем перекодировка лишь после подтверждения CP1251:
file -bi data.txt
iconv -f CP1251 -t UTF-8 data.txt > data-utf8.txt

Для записи используйте тоже явную кодировку: open('out.txt', 'w', encoding='utf-8'); по умолчанию Windows использует cp1251, а Linux — utf-8, и скрипты ведут себя по-разному. Рекомендуется везде хранить текстовые файлы в UTF-8 без BOM. Подробнее — в документации Python.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 1 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.