Telegram bot says "chat not found" — why bots cannot message you first
If your Telegram bot returns "chat not found", the ID is usually correct and the permission is missing. Bots cannot start conversations — here is the fix, and the four other causes worth checking.

If your Telegram bot returns a "chat not found" error, the most likely cause is not a wrong chat ID. It is that the person or group you are trying to message has never spoken to your bot — and until they do, that chat does not exist as far as your bot is concerned.
This catches almost everyone once. It reads like a lookup failure, so you go hunting for the right number. It is actually a permissions rule wearing a lookup error’s clothes.
A bot cannot start a conversation
Telegram does not allow bots to message people who have not contacted them first. It is a deliberate anti-spam rule and there is no way around it. A bot can only send to a user who has pressed Start or written to it, a group it has been added to, or a channel where it is an administrator.
So a chat ID is not a global address you can look up and use. It is an address your bot is permitted to use only once a relationship exists. A perfectly valid ID, copied correctly, still fails if that relationship was never established.
The fix, in order
Open the bot in Telegram and press Start, then send it any message at all. Now ask the bot API what it has received, by opening this address in a browser with your own bot token in place of the placeholder:
https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
The response is JSON. Inside it, each update contains a message, and each message contains a chat — and the id on that chat object is the number you want. For a private conversation it is a positive number that matches your own user ID. Use that number. Never a username.
If the result comes back as an empty list, the bot has received nothing. That is your answer rather than a separate problem: no message means no chat, and no chat means there is no ID to send to yet.
A second address is worth knowing while you are here. Adding getMe to the end instead of getUpdates returns the bot’s own name and username, which is the quickest way to confirm the token itself is valid before you start blaming anything else.
For groups, add the bot to the group and then post any message in it. The group will now appear in getUpdates, and group IDs are negative numbers.
One trap specific to groups. If a group is later upgraded to a supergroup, its ID changes — it becomes a much longer negative number, and the old one stops working immediately. Telegram announces this once, in a migration field on the message, and if your automation stored the old ID somewhere it will simply start failing with the same error you started with.
Why getUpdates returns nothing on an automated bot
Here is the part almost every guide leaves out, and it is the one that matters most if your bot is already wired into an automation platform.
A bot can receive updates in one of two ways: you poll for them with getUpdates, or Telegram pushes them to a webhook. It cannot do both. The moment something registers a webhook, polling stops working — and n8n, Make and every other platform with a Telegram trigger register one automatically the instant you activate the workflow.
So the standard advice fails silently for exactly the people most likely to need it. Instead of a chat ID you get a conflict error saying getUpdates cannot be used while a webhook is active.
Adding getWebhookInfo to the end of the same address tells you whether one is registered — if it returns a URL, that is your answer. You can remove it with deleteWebhook, read your updates, then re-register by deactivating and reactivating the workflow. Just be aware the bot stops receiving anything in the meantime, so do not leave it in that state.
There is a much easier route, though, and it is the one we use. Your automation platform already has the chat ID. Open the Telegram trigger node, put it into test mode, and send the bot a message — the execution output contains the whole update, chat object included. No token juggling, no webhook to break, and it works while everything stays running.
Failing that, message a lookup bot such as userinfobot inside Telegram. It replies with your numeric ID and touches nothing in your setup at all.
When you have done all that and it still fails
Four remaining causes, roughly in the order they turn out to be the problem.
The ID belongs to a different bot. Chat IDs are per-user, but the permission is per-bot. If you tested with a development bot and deployed with a production token, the second bot has no relationship with that chat and never did. This is easy to do and easy to miss, because the ID itself is genuinely correct.
You used a username instead of an ID. An @name works for public channels and for nothing else. Users and groups need the numeric ID.
The value never reached the request. An empty string, a stray space, or an unresolved template variable all produce the same error. If the chat ID is built from an expression, check the resolved value before sending — an expression that quietly evaluates to nothing sends an empty chat ID, and the API reports that as a missing chat rather than a missing parameter.
The user blocked the bot. This normally surfaces as a "forbidden" error rather than "not found", but a deleted chat can present either way. Worth checking when something worked for months and then stopped for one specific person.
Telling the two errors apart
Telegram has two rejections and they point at completely different fixes. A bad request, chat not found means the bot has no record of this chat: nobody has messaged it, or the ID is wrong. A forbidden, bot was blocked by the user means the chat exists and the person has explicitly cut the bot off.
The first is a setup problem. The second is a people problem, and no amount of configuration will solve it.
The version of this we see most often
In n8n workflows, two variants come up again and again.
The field was never filled in. Templates and generated workflows often ship with a placeholder sitting in the Chat ID field. It looks like configuration, so it survives review, and it gets handed to Telegram verbatim as a chat identifier. Check the raw value in the field rather than what you remember putting there.
The expression resolves to nothing. When Chat ID references an earlier node and that node’s output shape changes, the expression returns nothing at all and no warning is raised. Open the node and confirm the resolved value is a number before running anything.
There is a design note worth taking from this. In any workflow that replies to an incoming message, take the chat ID from the trigger rather than hardcoding it. That chat is guaranteed to exist, because the message you are answering came from it. Hardcoded IDs are only needed for notifications your system starts — and those are precisely the ones that break.
The wider point
Messaging platforms have a habit of reporting permission failures as lookup failures. WhatsApp does the same thing when you message outside its 24-hour window. So do most channel APIs, and the instinct every time is to re-check the identifier — which is almost always fine.
When something cannot be found in a messaging API, ask first whether you are allowed to reach it. That question resolves this class of bug far faster than checking the number again.
It is a small reframe, and it turns an afternoon of hunting for the right ID into a two-minute fix.
- Telegram
- n8n
- Automation
- Debugging


