Why your Discord bot keeps going offline (and how to fix it)

A Discord bot goes offline when its process stops or when the Gateway rejects its connection. Read the last error in your log: it usually names the cause.

Updated 6 min read

Learning objectives

After reading this article you will be able to:

  • Identify the cause from the error in your log
  • Fix invalid tokens, intents and crashes that kill the process
  • Keep the bot from going down again with error handling and automatic restarts
On this page

You open Discord, look at the member list and your bot is grey. Or worse: it used to stay online and now drops every so often. To Discord, "offline" means one thing: your bot has no active, authenticated connection to the Gateway. Your job is to find out why that connection does not exist.

There are two very different scenarios. Either the process died (the program stopped running), or the process is alive but the Gateway refused or dropped the connection. The first question in any diagnosis is which of the two you have, and the log answers it.

Bot offlineIs the process running?noCrash logexception, memoryor machineyes4004invalidtoken4014disabledintentinvisiblepresence,no error
Process stopped: read the crash log. Process alive: look for close code 4004 or 4014, or an invisible presence.

How do I tell if the process crashed or just lost its connection?#

Open your host's log (or the terminal, if you run locally) and scroll to the end.

  • If the log ends with a stack trace and the process exited, the process died: an exception, out of memory, or the machine shut down. See the exception and memory sections.
  • If the process keeps running and the log shows a connection close with code 4004 or 4014, the Gateway refused it: token or intents.
  • If there is no error and the bot answers commands but looks offline, check whether your code sets the presence to invisible.

This step avoids the most common mistake: changing code without knowing which cause is yours.

Is the token invalid or was it reset?#

This is the most common reason a bot never comes online. The exact messages:

text
Error [TokenInvalid]: An invalid token was provided.
text
discord.errors.LoginFailure: Improper token has been passed.

At the protocol level, the Gateway closes the connection with code 4004, "The account token sent with your identify payload is incorrect", and does not allow reconnecting with that token.

Typical causes: you reset the token in the Developer Portal and forgot to update the environment variable, you copied it with a stray space or quote, or it leaked and was regenerated. Generate a new one on the application's Bot page, store it in an environment variable (never in code) and restart. If you suspect a leak, read how to protect your bot token.

Are the privileged intents turned off?#

If your code requests GuildMembers, GuildPresences or MessageContent, they must be enabled in the Developer Portal. Otherwise the Gateway closes the connection with code 4014 (disallowed intent) and the bot never connects. The common errors:

text
Error: Used disallowed intents
text
discord.errors.PrivilegedIntentsRequired: Shard ID None is requesting privileged intents that have not been explicitly enabled in the developer portal.

Older discord.js v14 releases print Error [DisallowedIntents]: Privileged intent provided is not enabled or whitelisted. instead of Error: Used disallowed intents.

The fix: in the Developer Portal, open your application, go to the Bot page and, under Privileged Gateway Intents, switch on the ones your bot uses. Then restart. Apps with fewer than 10,000 users only need the toggle; above that, and for verified bots (required at 100+ servers), the intent must be approved by Discord. Code 4013 is a different problem: the intents bitfield was calculated wrong.

Request only the intents you use. In discord.js v14:

js
import { Client, GatewayIntentBits } from "discord.js";

const client = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages],
});

await client.login(process.env.DISCORD_TOKEN);

Is an unhandled exception killing the process?#

In Node.js, an exception or a rejected Promise without a catch ends the process and the bot goes offline with no warning. That explains the bot that "goes down by itself" after hours, when a rare event hits an untested code path.

Log unexpected errors instead of dying silently:

js
process.on("unhandledRejection", (reason) => {
  console.error("Unhandled promise rejection:", reason);
});

process.on("uncaughtException", (error) => {
  console.error("Uncaught exception:", error);
});

client.on("error", (error) => console.error("Client error:", error));
client.on("shardError", (error) => console.error("WebSocket error:", error));

This keeps the process alive through an isolated error and leaves the stack trace in the log. If the bot's state could be corrupted after an uncaughtException, the safest move is to log the error and exit on purpose, letting a supervisor restart the process. What matters is that the crash leaves a trace in the log and that something brings the bot back up.

Did the bot run out of memory?#

If the log ends abruptly with no stack trace, suspect an out-of-memory kill: the system or container terminates the process when it passes the limit. In bots the culprit is usually a cache growing unchecked (members, messages, presences), global lists that are never emptied, or image processing. Watch RAM usage over time: if it climbs steadily until the crash, it is a leak or an oversized cache. Limit the client's caches, drop what you do not use and, if the bot truly needs more, raise the RAM.

Is your machine or host shutting the bot down?#

If you run the bot on your own computer, it disappears when the PC sleeps, restarts or loses internet. On hosts that suspend idle processes or cap usage hours, the same thing happens without you touching anything. Either way, the fix is the same: a bot that must stay online all day needs a supervised process that restarts itself if it stops, running on something that does not shut off. See why the bot dies when your PC turns off and how to keep a bot online 24/7.

Can restarting in a loop make things worse?#

Yes. Every new login to the Gateway counts as an IDENTIFY, and Discord limits a bot to 1000 IDENTIFY calls per 24 hours across all shards. If the bot crashes and comes back in a loop, it hits that limit: active sessions are terminated and the token is reset, with an email to the owner. So when fixing a crash, do not force repeated restarts: read the error, fix the cause and restart once. Libraries such as discord.js and discord.py already handle reconnecting and resuming a session (RESUME, which does not count as an IDENTIFY), so do not write your own reconnect loop.

How to do this on Square Cloud#

On Square Cloud, the first diagnostic step happens in the dashboard. Logs stream in real time in the dashboard, the CLI, VS Code and the mobile app, and lines from before a restart stay visible, so the crash's stack trace does not vanish when the application comes back. That is where you read the 4004, the 4014 or the exception that killed the process. You can also ask the dashboard's AI assistant to read those logs and point to the likely cause.

Each cause in this article has a known place to fix it:

  • Token or intents: replace DISCORD_TOKEN in the application's environment variables, turn the intents on in the Developer Portal and restart once. The change applies on the next restart.
  • Exception: automatic restart, on by default for dashboard deploys, brings the bot back when the process exits with an error.
  • Memory: the CPU and RAM metrics show whether usage climbs until the crash. Running out of memory stops the application, and it only comes back when you raise the RAM in its settings and start it again.
  • A machine that shuts down: the container stays on, with no sleep mode and no inactivity rule.

A bot takes from 256 MB of the plan's RAM pool, and Hobby costs R$12.49 per month for 1 GB. See the details at Discord bot hosting.

Bot hosting

Keep your bot online 24/7 with automatic restarts

Learn more

FAQs

Why does my bot show offline while the code is running?

The process can be alive without a Gateway connection: an invalid token, an unauthorized intent or failed reconnects. Look in the log for a connection close with code 4004 or 4014. Also check that the bot's presence is not set to invisible.

What does Discord error 4014 mean?

It is the Gateway close code for a disallowed intent: the bot requested a privileged intent that is not enabled in the Developer Portal. Turn the intent on in the application's Bot page and restart the bot.

My bot goes down by itself after a few hours. What could it be?

The usual suspects are an unhandled exception, running out of memory, and the machine or hosting plan suspending the process. The log from the moment of the crash shows which one it was.

Can restarting the bot in a loop cause problems?

Yes. Discord limits bots to 1000 IDENTIFY calls per 24 hours. If a restart loop exceeds that, all sessions are terminated and the bot token is reset.

Next articleHow to host a Telegram bot 24/7To keep a Telegram bot online 24/7, run its process on an always-on server using long polling or a webhook. See working code and the common errors.