Telegram Bot API · error code

Telegram error 400: Bad Request: message not found

Permanent - do not retryHTTP 400400 Bad Request: identifiers, content and rights

Last verified against Telegram Bot API reference

What Telegram returns
Bad Request: message not found

What error 400 means

You referenced a message_id that does not exist in the given chat, or no longer exists, or is not one your bot is allowed to see. Telegram returns this from methods such as pinChatMessage, forwardMessage, copyMessage and setMessageReaction. The closely related message to delete not found and message to edit not found variants carry the method name in the description; the plain form is used by everything else.

Message IDs are scoped to a chat. ID 42 in one chat has nothing to do with ID 42 in another, so combining a stored message_id with the wrong chat_id produces exactly this error. In private chats with a bot the numbering is per conversation; in supergroups and channels it is per chat as well.

This is not a permissions failure. If the bot lacked rights you would get a not enough rights description instead.

What it looks like

{"ok":false,"error_code":400,"description":"Bad Request: message not found"}

Why it happens

  • The message was deleted by a user, an admin, or your own bot before the call ran.
  • A message_id from one chat was used with a different chat_id.
  • The message was sent in a forum topic or a different thread than the one you addressed, and the identifiers were mixed up.
  • The bot joined the group after the message was sent, so it never received it and cannot reference it.

How to fix Telegram error 400

  1. 1Log both chat_id and message_id on every send and store them as a pair; look the pair up rather than the ID alone.
  2. 2Catch this error around pin, forward and reaction calls and treat it as 'already gone' rather than a retryable failure.
  3. 3For forwards and copies, confirm the bot was a member of from_chat_id when the message was posted.
  4. 4If a deploy changed how you persist IDs, check that the message_id field is not being reset or reused.

How to stop it recurring

Persist (chat_id, message_id) tuples and never a bare message_id. Wrap post-hoc operations (pin, react, forward) in a handler that downgrades this error to a log line, since users deleting messages is normal behaviour and not a fault. Avoid scheduling actions on messages far in the future without re-validating them first.

Like the other not-found variants, this arrives as a plain 400 (BadRequest / TelegramBadRequest); there is no dedicated exception class in any major library, so the description string is what you match. When the failing call is a delete, see the more specific message to delete not found; when the message exists but cannot be touched, you get message can't be edited instead.

Official reference: Telegram Bot API reference. See all Telegram error codes or the Telegram limits and quotas.

Related codes

Error 400 - quick answers

What does Telegram error 400 mean?

You referenced a message_id that does not exist in the given chat, or no longer exists, or is not one your bot is allowed to see. Telegram returns this from methods such as pinChatMessage , forwardMessage , copyMessage and setMessageReaction . The closely related message to delete not found and message to edit not found variants carry the method name in the description; the plain form is used by everything else.

How do I fix Telegram error 400?

1. Log both chat_id and message_id on every send and store them as a pair; look the pair up rather than the ID alone. 2. Catch this error around pin, forward and reaction calls and treat it as 'already gone' rather than a retryable failure. 3. For forwards and copies, confirm the bot was a member of from_chat_id when the message was posted. 4. If a deploy changed how you persist IDs, check that the message_id field is not being reset or reused.

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.