2 октября 2026 г.
Telegram Unauthorized и TokenValidationError: бот не принимает токен
Бот падает сразу при старте с TelegramUnauthorizedError: Unauthorized, telegram.error.InvalidToken, TokenValidationError: Token is invalid! или просто 401 Unauthorized. Telegram отказывается разговаривать с этим токеном.
Что значит эта ошибка
Токен бота — это и логин, и пароль одновременно. Ошибок тут две разных:
TokenValidationError(aiogram) илиInvalidToken— библиотека даже не стала отправлять запрос: строка не похожа на токен. Часто это значит, что токена нет вообще: в код пришлоNone.Unauthorized/401— запрос ушёл в Telegram, и тот ответил: такого токена нет. Он неверный или отозван.
Причины по убыванию вероятности
- Переменная в коде называется иначе. В коде
os.getenv("TOKEN")илиos.getenv("API_TOKEN"), а на сервере заданаBOT_TOKEN. getenv молча возвращаетNone, и библиотека падает на проверке. - Токен брался из .env, а .env не попал на сервер. И правильно, что не попал: секретам не место в git. Но тогда
load_dotenv()ничего не находит, и сноваNone. - Токен скопирован с мусором: пробел или перенос строки в конце, кавычки вокруг, обрезан последний символ.
- Токен отозван. Вы (или кто-то с доступом) нажали
/revokeв @BotFather. Старый токен перестаёт работать мгновенно. - Токен от другого бота или тестового сервера Telegram.
Как исправить
- Проверьте сам токен одной командой. Если он живой, Telegram вернёт имя бота:
curl "https://api.telegram.org/bot<ТОКЕН>/getMe"
"ok":true— токен в порядке, проблема в том, как он попадает в код.401— возьмите новый токен в @BotFather (/mybots→ бот → API Token). - Сверьте имя переменной в коде с тем, что задано на сервере. Надёжнее читать токен так, чтобы при пустом значении бот сразу сказал, в чём дело:
import os TOKEN = os.getenv("BOT_TOKEN") if not TOKEN: raise SystemExit("Не задан BOT_TOKEN") - Уберите пробелы на всякий случай:
os.getenv("BOT_TOKEN", "").strip(). - Если токен когда-то лежал прямо в коде публичного репозитория — сделайте
/revokeи выпустите новый. Боты сканируют GitHub на токены за минуты.
Как это устроено в botdepo
Токен бота, который вы вводите при создании, попадает в контейнер как переменная окружения BOT_TOKEN. Читайте его через os.getenv("BOT_TOKEN"). Если в коде переменная называется иначе, проще добавить её в «Переменные окружения» под нужным именем. Если бот упадёт с Unauthorized, в логе рядом с ошибкой будет подсказка и ссылка на этот разбор. Задеплоить бота.
Частые вопросы
Локально работает, на сервере Unauthorized — как так?
Почти всегда локально токен приходит из .env, которого на сервере нет, или переменная названа по-разному. Сам токен один и тот же — проверьте getMe.
Сделал /revoke — что ещё поменять?
Новый токен нужно вписать везде, где запущен бот, включая сервер. Старый уже не заработает.