NewSchokr 13 is here. A whole new UI, seven locations, snapshots and more. Read more →

Why does my Discord bot keep going offline or crash looping?

Stop a Discord bot from crashing or restarting in a loop: catch unhandled errors, fix memory limits and avoid hitting Discord's session start limit.

Updated · 2 min read

A bot goes offline when its process exits. Schokr servers don't sleep when idle, so if your bot keeps dropping, something is making the process stop: an uncaught error, running out of memory, or a login problem. The console output right before it stops tells you which.

Step 1: read the last lines in the console

Open your server's console and look at the output just before the server stopped. See reading bot logs. Then match it to a cause below.

What you seeLikely cause
A stack trace, then the process exitsUnhandled error or promise rejection
No error, the server just stops while memory is near the limitOut of memory
TokenInvalid or LoginFailureBad token. See invalid token errors
Used disallowed intents or PrivilegedIntentsRequiredSee privileged intents
Cannot find module or ModuleNotFoundErrorSee module not found errors

Unhandled errors in discord.js

Since Node.js 15, an unhandled promise rejection crashes the whole process. One failed reply() (for example, Missing Permissions) can take your bot down. Catch errors where they happen, and add a safety net:

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

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

client.on('error', (error) => console.error('Client error:', error));

Wrap command handlers too:

client.on(Events.InteractionCreate, async (interaction) => {
  try {
    await handleCommand(interaction);
  } catch (error) {
    console.error(error);
    if (interaction.isRepliable() && !interaction.replied && !interaction.deferred) {
      // MessageFlags is imported from discord.js
      await interaction.reply({ content: 'Something went wrong.', flags: MessageFlags.Ephemeral }).catch(() => {});
    }
  }
});

The global handlers are a safety net, not a fix. Log the error and fix the code that throws it.

Errors in discord.py

discord.py catches errors inside commands and events and logs them without exiting, so a Python bot usually stays online. It can still stop if:

  • Code runs before bot.run() and raises (bad import, missing env variable).
  • A tasks.loop raises: the loop stops silently while the bot stays up. Add an error handler to the loop.
  • You call blocking code (like time.sleep or requests) inside async handlers. The heartbeat is blocked and Discord disconnects the bot. Use asyncio.sleep and an async HTTP library such as aiohttp.

Add a global command error handler so you see problems:

@bot.event
async def on_command_error(ctx, error):
    print(f"Command error in {ctx.command}: {error!r}", flush=True)

Out of memory

If the bot uses more memory than the server's limit, the process is killed with no error from your code. Check the Resources view. Either give the server more memory from your team's pool, or reduce usage; see reducing bot memory usage.

Don't let it restart endlessly

Every time a bot logs in it uses one "session start". Discord allows a limited number per day (1,000 for most bots). If a crash loop burns through them, Discord terminates the bot's sessions and resets its token, and you'll get an email about it. If your bot is crash looping, stop the server, fix the cause, then start it again.

Bot shows offline but the server is running

  • The process is stuck before login (for example, waiting on a database connection). Add a log line before login() / run().
  • A second copy elsewhere is using the same token. Stop any local copies.
  • Check status.schokr.gg and Discord's own status page for outages.

Still stuck?

Share the last 30 or so console lines (token removed) in the Schokr Discord.