Telegram Bot API · error code

Telegram error 400: Bad Request: query is too old and response timeout expired or query ID is invalid

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

Last verified against Telegram Bot API reference

What Telegram returns
Bad Request: query is too old and response timeout expired or query ID is invalid

What error 400 means

answerCallbackQuery (and the equivalent for inline and shipping/pre-checkout queries) was called with a callback_query_id that Telegram no longer accepts. Every query must be answered within a short window after the user taps; once that passes, or if the ID was already answered, or if it is malformed, Telegram returns this combined description. It does not tell you which of the three applied.

The user experience of this error is a button that shows a loading spinner for a while and then gives up. Your handler probably ran, and may even have edited the message correctly; it just did not acknowledge the tap in time.

This is never a token or permission issue. It is timing or ID reuse.

What it looks like

{"ok":false,"error_code":400,"description":"Bad Request: query is too old and response timeout expired or query ID is invalid"}

Why it happens

  • The handler does slow work (a database query, an LLM call, an HTTP request) before answering the callback.
  • Updates were queued for a long time (bot was down, webhook backlog, polling paused) and are now being replayed.
  • The same callback was answered twice, or the ID was persisted and reused.
  • Two bot instances processed the same update and the second one is late.

How to fix Telegram error 400

  1. 1Call answerCallbackQuery first, before any other work, optionally with no text.
  2. 2When draining a backlog after downtime, either skip callback answers for old updates or start with drop_pending_updates.
  3. 3Catch this error and ignore it; there is nothing further to do for that query.
  4. 4Ensure exactly one instance consumes updates.

How to stop it recurring

Adopt 'acknowledge then act' as a rule for every callback. If a button triggers long work, answer immediately and edit the message when done. Filter replayed updates by message.date so stale callbacks do not reach handlers after an outage.

The companion failure is an edit that no-ops because the content did not change, which surfaces as message is not modified; sloppy handlers often produce both on the same tap. The answer toast itself is capped at 200 characters (see keyboard and callback limits), so long explanations belong in the edited message, not the callback answer.

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?

answerCallbackQuery (and the equivalent for inline and shipping/pre-checkout queries) was called with a callback_query_id that Telegram no longer accepts. Every query must be answered within a short window after the user taps; once that passes, or if the ID was already answered, or if it is malformed, Telegram returns this combined description. It does not tell you which of the three applied.

How do I fix Telegram error 400?

1. Call answerCallbackQuery first, before any other work, optionally with no text. 2. When draining a backlog after downtime, either skip callback answers for old updates or start with drop_pending_updates . 3. Catch this error and ignore it; there is nothing further to do for that query. 4. Ensure exactly one instance consumes updates.

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.