Telegram error 400: Bad Request: chat not found
Last verified against Telegram Bot API reference
Bad Request: chat not foundWhat error 400 means
The chat_id you passed does not resolve to any chat your bot can see. Telegram is not saying the chat is closed or that you lack permission; it is saying that, from your bot's point of view, no such chat exists. That distinction matters because it points at the identifier, not at rights or content.
Bots never get a directory of chats. A chat becomes visible only after the bot has received at least one update from it, which is why a freshly created bot returns this error for every user until they send /start. It is also why the same request works from one bot token and fails from another: visibility is per bot. If the user genuinely has never started the bot, you may instead see bot can't initiate conversation with a user; which of the two appears depends on whether the bot has ever encountered the ID.
The token and method are fine; otherwise you would see 401 or 404. In python-telegram-bot this surfaces as telegram.error.BadRequest with this description; aiogram v3 raises TelegramBadRequest; Telegraf and grammY throw a 400 TelegramError / GrammyError; node-telegram-bot-api reports ETELEGRAM: 400 Bad Request: chat not found. No library retries it for you, because it is deterministic for a given (bot, chat_id) pair.
For groups, the highest-value check is migration: when a basic group becomes a supergroup its ID changes to a -100... value and the old ID stops resolving. That case has its own error with the replacement ID attached; see group chat was upgraded to a supergroup chat.
What it looks like
{"ok":false,"error_code":400,"description":"Bad Request: chat not found"}Why it happens
- The user has never started a conversation with this bot, so the bot has no record of their private chat.
- A username was passed where a numeric ID is required (usernames only work for public channels and supergroups as @name).
- The group was upgraded to a supergroup and the old (negative, non -100) chat ID is being reused; the old ID is dead.
- The ID was stored in a 32-bit integer column and truncated, or the leading minus sign was dropped on the way through a form or CSV.
- The ID belongs to a different bot's database (staging data in production, or an import from another system).
How to fix Telegram error 400
- 1Log the exact
chat_idstring that went out, including its sign, and compare it byte for byte with what you received in the original update. - 2For private chats, confirm the user has actually pressed Start on this bot; ask them to send /start and retry.
- 3For groups that worked before, look in your update history for
migrate_to_chat_idand switch to the new -100... identifier. - 4Check the column type: chat IDs need a 64-bit signed integer or a string (the API documents up to 52 significant bits).
- 5Verify with
getChat?chat_id=...from the same token; if that also fails, the ID is wrong for this bot.
How to stop it recurring
Store chat IDs as 64-bit signed integers or strings the moment you receive them, never re-typed by hand. Handle migrate_to_chat_id as a first-class event that rewrites the stored ID. Keep one database per bot token so staging IDs never reach production. When this error comes back for a private chat, mark the contact as unreachable rather than retrying. Identifier mistakes are cause 8 in Telegram bot not responding.
Official reference: Telegram Bot API reference. See all Telegram error codes or the Telegram limits and quotas.
Related codes
- 400: Bad Request: user not foundBad Request: user not found
- 400: Bad Request: group chat was upgraded to a supergroup chatBad Request: group chat was upgraded to a supergroup chat
- 403: Forbidden: bot can't initiate conversation with a userForbidden: bot can't initiate conversation with a user
- 400: Bad Request: chat_id is emptyBad Request: chat_id is empty
Error 400 - quick answers
What does Telegram error 400 mean?
The chat_id you passed does not resolve to any chat your bot can see. Telegram is not saying the chat is closed or that you lack permission; it is saying that, from your bot's point of view, no such chat exists. That distinction matters because it points at the identifier, not at rights or content. Bots never get a directory of chats.
How do I fix Telegram error 400?
1. Log the exact chat_id string that went out, including its sign, and compare it byte for byte with what you received in the original update. 2. For private chats, confirm the user has actually pressed Start on this bot; ask them to send /start and retry. 3. For groups that worked before, look in your update history for migrate_to_chat_id and switch to the new -100... identifier. 4. Check the column type: chat IDs need a 64-bit signed integer or a string (the API documents…
Should I retry after error 400?
No. Retrying the same request produces the same error; the condition has to be fixed first. Treat it as a permanent failure for that message and surface it, rather than looping.
Stop debugging Telegram by hand
Connect the channel through Conferbot: tokens, webhooks and retries are handled, failures show as readable status.