NapNodes

← Discord bot guides

Discord bots · updated 24 October 2026

Discord Bot Not Responding (or Showing Offline): Causes and Fixes

It's almost always one of five things: the bot's program isn't running, the token is wrong, the Message Content Intent is missing, the bot has no permission in that channel, or Discord is rate limiting it (error 429). The console tells you which: here's each error and its fix, in discord.py and in discord.js.

First, check the console

The terminal where you start the bot (or the panel's “Console”, if it's hosted) is the first place to look. If the bot never prints your “Logged in as…”, it hasn't connected, and the error just above says why. If it does print it and still doesn't reply, the problem is in the intents, the permissions or your code.

A tip: copy the error exactly as it is. The sections below quote the exact messages discord.py 2.7 and discord.js 14 print, so you can search for them quickly.

Rather not set it up yourself? Discord bot hosting from €1.50 a month, no contract and a full refund within 72 hours. Or create a free Discord bot, no card needed.

The bot shows offline: the program isn't running

A bot is only “online” while its program is running. If you start it on your computer, it disconnects when you close the terminal, shut down or put the PC to sleep, or when the connection drops. It's not a bug in your code: the program has to be running somewhere.

On free platforms built for websites (Replit, Render…), the program falls asleep if nobody visits its page, and a bot gets no visits: that's why it disconnects on its own after a while (why it happens and free options that really keep it online). To keep it online all the time, see the Discord bot hosting guide.

If the bot crashes and restarts over and over, fix the error before leaving it like that: Discord allows 1000 logins (IDENTIFY) per bot every 24 hours, and when you go over, it closes all its sessions, resets the token and emails you.

Token error: “Improper token has been passed” or “TokenInvalid”

discord.py prints “discord.errors.LoginFailure: Improper token has been passed.” and discord.js “Error [TokenInvalid]: An invalid token was provided.”. Both mean the same thing: the token your code reads isn't the right one. discord.js also gives TokenInvalid if the token arrives empty, which is what happens when the .env isn't in the folder or the variable has a different name.

Typical causes: it was copied with an extra space or quotes; someone clicked “Reset Token” in the portal (the old token stops working at that moment); or the token was published in a public GitHub repository, and GitHub scans public code for Discord tokens and tells Discord so it can revoke them (if that's what happened, what to do when your token leaks).

  1. Get a new token

    At discord.com/developers/applications, your application → “Bot” → “Reset Token”. Copy all of it; it's only shown once.

  2. Paste it into the .env

    DISCORD_TOKEN=the-token, with no quotes or spaces. The .env has to be in the same folder as the bot (and out of any public repository).

  3. Restart the bot

    The token is only read at startup. If the bot is hosted, upload the new .env and restart it.

It's connected but can't read messages: Message Content Intent

If your bot uses prefix commands (!ping) or reads what people type, it needs the Message Content Intent. Without it, Discord sends it messages with the text empty: the bot is online, receives the message and doesn't see “!ping”, so it doesn't reply. There are three exceptions: messages the bot sends itself, direct messages and messages that mention it.

It has to be turned on in two places: in the Developer Portal and in your code. With 100 servers or more the bot has to be verified and Discord has to approve the intent; for a small bot, the toggle is enough. Slash commands don't need this intent.

In discord.py, if you use commands.Bot with a prefix and it's missing, the warning is “Privileged message content intent is missing, commands may not work as expected.”. Here's a minimal bot that reads messages in each library:

app.py (discord.py)
import os

import discord
from dotenv import load_dotenv

load_dotenv()

intents = discord.Intents.default()
intents.message_content = True  # and turn it on in the portal
client = discord.Client(intents=intents)


@client.event
async def on_ready():
    print(f"Logged in as {client.user}")


@client.event
async def on_message(message: discord.Message):
    if message.author.bot:
        return
    if message.content == "!ping":
        await message.channel.send("pong")


client.run(os.environ["DISCORD_TOKEN"])
index.js (discord.js)
require("dotenv").config();
const { Client, Events, GatewayIntentBits } = require("discord.js");

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent, // and turn it on in the portal
  ],
});

client.once(Events.ClientReady, (c) => console.log(`Logged in as ${c.user.tag}`));

client.on(Events.MessageCreate, async (message) => {
  if (message.author.bot) return;
  if (message.content === "!ping") await message.reply("pong");
});

client.login(process.env.DISCORD_TOKEN);
  1. Turn it on in the portal

    discord.com/developers/applications → your application → “Bot” → “Privileged Gateway Intents” → “Message Content Intent”, and save the changes.

  2. Request it in your code

    In discord.py, intents.message_content = True; in discord.js, GatewayIntentBits.MessageContent alongside Guilds and GuildMessages, as in the examples.

  3. Restart the bot

    Intents are requested when the bot connects: until you restart, nothing changes.

Intents error: PrivilegedIntentsRequired or DisallowedIntents

This is the opposite case: your code requests a privileged intent (message content, members or presence) that isn't turned on in the portal, and Discord closes the connection. discord.py says “PrivilegedIntentsRequired: Shard ID None is requesting privileged intents that have not been explicitly enabled in the developer portal” and discord.js “Error [DisallowedIntents]: Privileged intent provided is not enabled or whitelisted.”.

Fix: in the portal, “Bot” → “Privileged Gateway Intents”, turn on the same ones you request in your code (Message Content, Server Members or Presence) and restart. If you don't need them, take them out of your code: it's better to request only what your bot uses.

It doesn't reply in one channel: channel or role permissions

If the bot replies in one channel and not in another, it's permissions. To post it needs “View Channels” and “Send Messages”; to reply in threads, also “Send Messages in Threads”; to send embeds, “Embed Links”. A channel's permissions can take away what its role gives it: check under “Edit Channel” → “Permissions” that neither the bot's role nor @everyone has those permissions denied.

If you invited it with too few permissions, build a new link with the ones it needs in the bot permissions calculator (with what each one lets it do) and open it: there's no need to kick the bot first. And if your bot manages roles, it can only give or take the ones below its own: move its role up in the server's role list.

The slash command says the application did not respond

Discord gives a slash command 3 seconds to reply. If your code takes longer (it calls a website, a database…) or never replies, Discord shows an error saying the application did not respond, even though the bot is online. If it's going to take a while, reply first with “thinking…” and then edit the reply: in discord.py, await interaction.response.defer() and then await interaction.followup.send(…); in discord.js, await interaction.deferReply() and then await interaction.editReply(…). You have 15 minutes for the final reply.

It also shows up if the command is published but your code doesn't handle it (for example, you deleted it from your code and it's still registered on Discord). And if the command doesn't even appear when you type /, that's a different problem: slash commands not showing up.

Discord's limits: error 429 (rate limit)

Discord limits how many requests a bot makes: 50 per second in total, and fewer for each kind of action (sending messages to a channel, changing roles…). Go over and it answers with a 429 and a time to wait. discord.py and discord.js wait and retry on their own; discord.py warns you in the console with “We are being rate limited… responded with 429. Retrying in … seconds.”.

The odd 429 is normal. If you get lots of them, your bot is doing too much: messages in a loop, renaming a channel every few seconds, mass direct messages… Also, if an IP address racks up 10,000 failed requests (401, 403 or 429) in 10 minutes, Discord blocks it for a while and the bot can't even connect. Fix: break the loop, and don't manually retry what the library already retries.

If your bot is on NapNodes

The panel lets you start it, watch the console and upload the code; errors in your code, as with any host, are yours to fix. How to set everything up, in the Discord bot hosting guide. What to check:

  1. Check the “Console”

    It shows what your bot prints: the “Logged in as…” or the error that stops it. With that and the sections above you'll know what to change.

  2. Check that it's running

    If it says “Offline”, click “Start”. The free bot has to be renewed every 7 days with “Start” or “Renew now”; if it isn't renewed, it stops (it isn't deleted) and shows as offline on Discord. Paid plans don't need renewing.

  3. Check the language, startup file and dependencies

    In “Settings”: the “Language” (Node.js or Python) has to be your bot's, and the startup file, yours (index.js or app.py by default). The libraries install at startup from package.json or requirements.txt: if discord.js or discord.py is missing there, the console will say it can't find the module.

  4. The .env goes in “Files”

    If you pull the code from GitHub without the .env (good call), upload it in “Files” next to the startup file, and restart.

Frequently asked questions

Why does my Discord bot show as offline?

Because its program isn't running: the terminal was closed, the PC was switched off, the platform put it to sleep or it stopped on an error. Check the console: if there's an error, it says which. To keep it online all the time it has to be hosted on a server.

My bot is online but doesn't respond to “!” commands

It's missing the Message Content Intent: turn it on in the portal (“Bot” → “Privileged Gateway Intents”) and in your code (intents.message_content = True in discord.py, GatewayIntentBits.MessageContent in discord.js), and restart.

What does “Improper token has been passed” mean?

That the token your bot uses isn't valid: badly copied, empty or regenerated with “Reset Token”. Get a new one in the portal, paste it into the .env without quotes and restart.

What is error 429 on a Discord bot?

Discord is slowing it down for making too many requests. The library waits and retries on its own; if it happens often, look for a loop in your code that sends messages or changes things non-stop.

The bot replies in one channel but not another. Why?

Because of that channel's permissions: it needs “View Channels” and “Send Messages”, and a channel can deny them even if its role has them. Check it under “Edit Channel” → “Permissions”.

Shall we set it up for you?

Discord bot hosting from €1.50 a month, never oversold: your RAM is yours alone. And if you'd rather start without paying, there's a free Discord bot, no card needed.

Free tool: Discord bot permissions calculator. Tick your bot's permissions and get the number and the invite link; or paste a number and see which permissions it grants.

Free tool: Discord intents calculator. Tick what your bot does or search the event you're not getting: the intents, the discord.js or discord.py code and what to enable in the portal.

Keep reading

All Discord bot guides, sorted →