Skip to main content
Share
Guides

Discord Bot Not Responding? The Intents Problem and 8 Other Causes

A Discord bot that shows online and ignores every command is almost always missing the Message Content intent. Here is that fix, plus gateway error 4014, permission code 50013, slash command propagation and the rest - each with the exact error and the exact remedy.

Content & Engineering
Aug 1, 2026
13 min read
Updated Aug 2026Expert Reviewed
discord bot not respondingdiscord bot not workingdiscord bot offlinemessage content intentdiscord gateway error 4014
TL;DR

A Discord bot that shows online and ignores every command is almost always missing the Message Content intent. Here is that fix, plus gateway error 4014, permission code 50013, slash command propagation and the rest - each with the exact error and the exact remedy.

Key Takeaways
  • "Bot offline" and "bot online but silent" are completely different failures.
  • Fixing one will never fix the other, and most wasted debugging time comes from treating them as the same problem.Last verified: August 2026 against the Discord Developer Portal and Gateway API.
  • Error codes quoted are the literal values Discord returns.SymptomWhat it provesLook atGrey / offline in member listNo gateway connection existsToken, process, close codes 4004 and 4014Green / online, ignores everythingConnected, but not receiving or not permittedMessage Content intent, channel permissionsOnline, works in one channel onlyConnected and receiving; permission overwrite blockingChannel-level permission overwritesSlash commands missing from menuCommands not registered, or still propagatingGlobal vs guild registration, applications.commands scopeIf your bot is green and ignoring messages, skip straight to the next section.
  • That is the single most common Discord bot problem, and it has one cause.

First, separate the two symptoms - they have nothing in common

"Bot offline" and "bot online but silent" are completely different failures. Fixing one will never fix the other, and most wasted debugging time comes from treating them as the same problem.

Last verified: August 2026 against the Discord Developer Portal and Gateway API. Error codes quoted are the literal values Discord returns.

SymptomWhat it provesLook at
Grey / offline in member listNo gateway connection existsToken, process, close codes 4004 and 4014
Green / online, ignores everythingConnected, but not receiving or not permittedMessage Content intent, channel permissions
Online, works in one channel onlyConnected and receiving; permission overwrite blockingChannel-level permission overwrites
Slash commands missing from menuCommands not registered, or still propagatingGlobal vs guild registration, applications.commands scope

If your bot is green and ignoring messages, skip straight to the next section. That is the single most common Discord bot problem, and it has one cause.

1. The Message Content intent - the cause of most silent bots

Since Discord's 2022 privacy changes, message content is a privileged intent. Without it, your bot still receives every MESSAGE_CREATE event, but the content field arrives as an empty string. Your command matching compares "" against "!help", finds no match, and does nothing - with no error, no exception and no log line.

That silence is what makes this so hard to diagnose. The bot is connected, events are flowing, your handler is running. It just cannot see what anyone typed.

The fix requires two changes, and people usually only make one

Step 1 - enable it in the portal. Go to the Discord Developer Portal, open your application, select Bot in the sidebar, scroll to Privileged Gateway Intents, and toggle on Message Content Intent. Save.

Step 2 - request it in your code. The portal toggle grants permission; your gateway connection must still ask for it. In discord.js:

const { Client, GatewayIntentBits } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,   // the one people forget
  ],
});

In discord.py:

import discord

intents = discord.Intents.default()
intents.message_content = True          # the one people forget

client = discord.Client(intents=intents)

Step 3 - restart the process. Intents are negotiated when the gateway connection is established. Changing the portal toggle while the bot is running has no effect until it reconnects. A surprising number of "I enabled it and it still doesn't work" reports are just a bot that was never restarted.

Three privileged intents, and what each unlocks

IntentNeeded forSymptom without it
Message ContentReading what users typePrefix commands silently never match
Server MembersJoin/leave events, full member listsWelcome messages never fire; role automation breaks
PresenceOnline status and activity trackingStatus-based features see everyone as offline

The 100-server wall

Once a bot reaches 100 servers it must be verified to continue using privileged intents. If you are approaching that number, apply early - verification is a manual review and takes time. Bots that hit 100 servers unverified lose privileged intents and go silent for their entire user base at once, which is a memorable way to discover this rule.

Or sidestep it: use slash commands

Slash command interactions deliver their arguments directly in the interaction payload, so they work without the Message Content intent at all. If your bot only needs explicit commands rather than reading ambient conversation, migrating from prefix commands to slash commands removes this entire problem - and removes the 100-server verification requirement along with it.

2. Gateway error 4014: disallowed intents

If the bot never comes online and the connection drops immediately, check for this close code:

Gateway closed: 4014 - Disallowed intent(s)

This is the exact inverse of the previous section: your code is requesting a privileged intent that the portal has not granted. Discord refuses the connection outright rather than downgrading it.

Two fixes, depending on what you actually need:

  • Enable the intent in the Developer Portal (Bot -> Privileged Gateway Intents), or
  • Remove it from your intents list in code if the bot does not genuinely require it

The frequent trigger is copying a starter template that requests Intents.all() or every GatewayIntentBits value. That works on a fresh unverified bot only if you have toggled all three privileges on. Request the minimum set your features need - it connects more reliably and delays the verification requirement.

The neighbouring close codes

CodeMeaningFix
4004Authentication failedToken is wrong, revoked, or has whitespace. Regenerate and redeploy.
4013Invalid intent(s)The intent bitfield contains an undefined value. Usually a hand-computed number.
4014Disallowed intent(s)Requesting a privileged intent not enabled in the portal.
4008Rate limitedToo many gateway payloads. Usually a reconnect loop.

Note the difference between 4013 and 4014: 4013 means the value is not a real intent, 4014 means it is real but you are not allowed it. If you are constructing the bitfield by hand, stop - use the library's named constants.

Try it yourself
Build your first chatbot free
Free plan, no credit card required. Live on your site in about 10 minutes.
Start building free

3. Token invalid, and the Git commit that killed it

Close code 4004 or an immediate Improper token has been passed means the token is bad. Beyond the usual copy-paste errors, one cause is worth calling out because it produces a bot that worked yesterday and does not today:

Discord automatically invalidates tokens it finds in public repositories. Their scanner monitors GitHub and other public sources. Commit your token, and it stops working - often within minutes, with no notification beyond an email to the application owner. If your bot died suddenly and nothing changed on your side, check whether the token reached a public repo, a Pastebin, a screenshot in a support thread, or a Discord message in a public channel.

The remedy is the same either way: regenerate the token in the Developer Portal, move it into an environment variable or secrets manager, and add the file that held it to .gitignore. Regenerating immediately invalidates the previous token, so redeploy everywhere at once or you will have half your instances failing.

Other reliable token failures:

  • Client secret used instead of bot token. They are different strings on adjacent pages of the portal. The client secret is for OAuth flows and will never authenticate a gateway connection.
  • The Bot prefix. The Authorization header needs Bot <token> with a space. Most libraries add this for you - if you are calling the REST API directly with fetch or curl, you must add it yourself.
  • Trailing newline from a secrets file. Trim the value before use.

4. Missing Permissions (50013) and Missing Access (50001)

Your bot is online, receiving events, and its replies never appear. The API is almost certainly returning:

{"message": "Missing Permissions", "code": 50013}
{"message": "Missing Access", "code": 50001}

Discord permissions resolve through several layers, and a bot can hold a permission at server level while being denied it in the exact channel where you are testing:

  1. @everyone server-wide permissions
  2. Permissions from each role the bot holds
  3. Channel-level overwrites - these override the above and are where the problem usually lives
  4. Category overwrites, inherited by channels that sync with the category

A single deny on a channel overwrite beats any allow granted higher up. Denies win.

Check it the fast way

Server Settings -> Roles -> select your bot's role -> the permission list shows server-wide grants. Then right-click the specific channel -> Edit Channel -> Permissions, and look for the bot's role or the bot itself with a red X.

The permissions a conversational bot needs in each channel it works in:

  • View Channel - without it the bot cannot see the channel exists
  • Send Messages - the obvious one
  • Read Message History - required to reply to a specific message
  • Embed Links - rich embeds are silently dropped without it
  • Attach Files - only if you send images or documents
  • Use External Emojis - if your replies use emojis from other servers

The role hierarchy rule

A bot can only manage roles below its own highest role in the list. A moderation bot that cannot assign a role, kick a member or add a nickname is usually positioned too low in Server Settings -> Roles. Drag the bot's role above the roles it needs to manage. This produces the specific symptom of a bot that moderates most members successfully and fails on the ones with elevated roles.

Threads and forums are separate

Sending in a thread requires Send Messages in Threads, which is a distinct permission from Send Messages. A bot that works in a normal channel and fails in a thread has hit exactly this. Archived threads must also be unarchived before a message can post to them.

Calculate your chatbot ROI
See exactly how much a chatbot saves your business. Free calculator, no signup required.
Try Calculator

5. Slash commands that never appear

Registered commands that do not show in the client have three usual causes, in this order.

The applications.commands scope was missing from the invite

This is the big one, and it is invisible after the fact. If you invited the bot with a URL that requested only the bot scope, the server never authorised it to register slash commands - and no amount of re-registering fixes it. Your invite URL needs both:

https://discord.com/api/oauth2/authorize?client_id=YOUR_ID&permissions=YOUR_PERMS&scope=bot%20applications.commands

The fix is to re-invite the bot using a URL that includes applications.commands. You do not need to kick it first - visiting the corrected URL and re-authorising adds the missing scope to the existing installation.

Global commands take up to an hour

Global commands propagate across Discord's infrastructure and can take up to one hour to appear. Guild-scoped commands register instantly. During development, always register to a single test guild - otherwise you will spend an afternoon convinced your registration code is broken when it worked the first time.

// Instant - use during development
await rest.put(Routes.applicationGuildCommands(clientId, testGuildId), { body: commands });

// Up to 1 hour - use for production release
await rest.put(Routes.applicationCommands(clientId), { body: commands });

Command permissions are restricting visibility

Server admins can restrict which roles and channels a command appears in, via Server Settings -> Integrations -> your bot. A command that is invisible to regular members but visible to you as an admin has been restricted here, not broken in code.

The 3-second interaction deadline

A separate and very common failure: you must acknowledge an interaction within 3 seconds or Discord shows "The application did not respond" and the interaction token becomes invalid. Any bot that calls an AI model, queries a database or hits an external API will exceed this.

Defer immediately, then follow up:

await interaction.deferReply();          // buys you up to 15 minutes
const answer = await callSlowThing();    // now take your time
await interaction.editReply(answer);

This single pattern accounts for most "my AI bot says it did not respond but the logs show it worked" reports.

6. DMs, mentions and the events you are not subscribed to

Guild messages and direct messages arrive through different intents. A bot subscribed to GuildMessages but not DirectMessages works perfectly in servers and ignores every DM:

intents: [
  GatewayIntentBits.Guilds,
  GatewayIntentBits.GuildMessages,
  GatewayIntentBits.DirectMessages,     // separate subscription
  GatewayIntentBits.MessageContent,
]

Two more DM-specific rules catch people out:

  • Users can block DMs from server members in their privacy settings. Sending to someone with this enabled returns Cannot send messages to this user (code 50007). There is no way to detect this in advance and no workaround - it is a user preference.
  • In discord.js, DM channels may need partials enabled to receive events for channels that were not cached at startup. Without Partials.Channel, DMs from users the bot has not interacted with in that session can be missed.

Mention matching that fails on nicknames

If your bot responds to being @-mentioned, do not string-match the mention text. When a user has a server nickname, the mention renders differently, and matching on <@123456> will miss <@!123456>. Use the library's mention helper - message.mentions.has(client.user) in discord.js - which handles both forms.

The infinite loop guard

Always ignore messages from bots, including your own, as the first line of your handler:

if (message.author.bot) return;

Without it, a bot that replies to messages will reply to its own reply, forever, until Discord rate limits it. Two bots in the same channel without this guard will do it to each other and generate thousands of messages in seconds.

7. Rate limits, reconnect loops and sharding

Discord returns 429 with a retry_after value in seconds. Well-maintained libraries queue and retry automatically, so if you are seeing raw 429s you are probably calling the REST API directly.

Two limits matter more than the general one:

  • Global: around 50 requests per second across your whole application.
  • Per route: tighter and specific. Message sends in a single channel are limited to roughly 5 per 5 seconds, which is easy to hit with a bot that splits replies into several bubbles.

Exceeding limits repeatedly can trigger a Cloudflare ban at the IP level, which returns HTML rather than JSON and lasts an hour or more. If your bot suddenly gets unparseable responses from the API, this is why - and it usually follows a reconnect loop.

Identify limits and the crash loop

Gateway identifies are limited to roughly 1,000 per day. A bot crash-looping on startup - throwing an exception after connecting, being restarted by the supervisor, connecting again - burns through that budget and gets locked out of connecting entirely. If a bot has been failing all day and now cannot connect at all even after the bug is fixed, wait for the daily reset.

Sharding at 2,500 guilds

Bots in 2,500 or more guilds must shard. Discord refuses the connection otherwise. Most libraries provide a sharding manager that handles this, but it is a deliberate step you have to take - it does not happen automatically as you grow.

The diagnostic order that finds it fastest

#QuestionIf no
1Is the bot green in the member list?Token (4004) or intents (4014). Read the gateway close code.
2Does console.log in your message handler print anything?Wrong intent for the event source - guild vs DM.
3Is message.content non-empty when it prints?Message Content intent. Portal toggle + code + restart.
4Does a manual send from that handler succeed?Permissions - 50013 or 50001. Check channel overwrites.
5Do slash commands appear in the menu?Missing applications.commands scope, or global propagation delay.
6Do interactions respond within 3 seconds?Call deferReply() first, then editReply().
7Are you logging full API error bodies?Discord's error codes are precise. Do not discard them.

Step 3 is the one to reach for first when the bot is online. Printing message.content and seeing an empty string is the definitive confirmation of the intents problem, and it takes ten seconds to check.

When to stop maintaining the plumbing

Everything above is transport-layer work: intent negotiation, gateway close codes, permission resolution, interaction deadlines, shard counts, identify budgets. None of it is your product. It is the toll for operating the Discord API directly, and it is the same toll for every bot on the platform.

That is a fine trade for a community bot you enjoy building. It is a worse one when Discord is a support or sales channel for a business, and considerably worse when Discord is one of several channels you are expected to keep alive - because each platform has an entirely different version of this same list.

Conferbot's Discord integration handles connection, intents, permissions and interaction deadlines for you: you connect the bot and build the conversation in a visual flow editor rather than in gateway code. The same flow runs on Telegram, WhatsApp, Slack and a website widget, with buttons and media adapting to each platform automatically.

Start free with Conferbot - the free plan includes 600 conversations a month and needs no credit card, so you can have the same flow running on a second channel this afternoon.

If you are debugging today, work the table above - if the bot is online and silent, it is the Message Content intent far more often than anything else. If you are on your third channel and writing the same plumbing a third time, that is the signal to stop.

Share this article:

Was this article helpful?

Ready to build your chatbot?

Join the businesses. Deploy on website, WhatsApp, and 11 more channels in minutes. Free forever plan available.

No credit cardNo coding13+ channels
Start Building Free

Get chatbot insights delivered weekly

Join 5,000+ professionals getting actionable AI chatbot strategies, industry benchmarks, and product updates.

🎯Automate this with a free chatbot

Build and deploy in 10 minutes. No coding needed.

FAQ

Discord Bot Not Responding? The Intents Problem and 8 Other Causes FAQ

Everything you need to know about chatbots for discord bot not responding? the intents problem and 8 other causes.

🔍
Popular:

Almost always the Message Content intent. Since 2022 it is a privileged intent, and without it your bot still receives message events but the content field arrives empty, so command matching silently never matches. Enable Message Content Intent in the Developer Portal under Bot -> Privileged Gateway Intents, add it to your intents array in code, and restart the process - all three steps are required.

Error 4014 means Disallowed intent(s): your code requests a privileged intent that is not enabled in the Developer Portal. Either enable that intent under Bot -> Privileged Gateway Intents, or remove it from your intents list if the bot does not need it. It is commonly caused by copying a template that requests Intents.all().

4013 means Invalid intent(s) - the bitfield contains a value that is not a real intent, usually from hand-computing the number. 4014 means Disallowed intent(s) - the intent is real but your application has not been granted it in the Developer Portal. Use your library's named intent constants to avoid 4013 entirely.

The API is likely returning code 50013 Missing Permissions or 50001 Missing Access. Channel-level permission overwrites beat server-wide role grants, so a bot can hold Send Messages at server level and be denied it in the specific channel you are testing. Check the channel's permission settings for a red X against the bot's role.

Three usual causes. The invite URL omitted the applications.commands scope, so the server never authorised command registration - re-invite with scope=bot%20applications.commands. Or you registered globally, which takes up to an hour to propagate; register to a test guild during development for instant results. Or a server admin restricted the command under Server Settings -> Integrations.

Your bot did not acknowledge the interaction within Discord's 3-second deadline, so the interaction token expired. Call deferReply() immediately on receiving the interaction, which extends your window to 15 minutes, then send the real answer with editReply(). This is the standard fix for any bot that calls an AI model or external API.

No. Slash command arguments arrive in the interaction payload itself, so slash commands work without the Message Content intent entirely. Migrating from prefix commands to slash commands removes this problem and also avoids the privileged-intent verification requirement at 100 servers.

Discord scans public sources including GitHub and automatically invalidates any bot token it finds. If your bot died with no change on your side, check whether the token reached a public repo, a screenshot, or a public message. Regenerate the token, move it into an environment variable, and redeploy everywhere at once since regenerating invalidates the old one immediately.

Role hierarchy. A bot can only manage roles positioned below its own highest role in Server Settings -> Roles. If it moderates most members successfully but fails on those with elevated roles, drag the bot's role above the roles it needs to manage. The bot also needs the Manage Roles permission itself.

Guild messages and direct messages use separate intents. Add GatewayIntentBits.DirectMessages alongside GuildMessages. In discord.js you may also need Partials.Channel to receive events for DM channels that were not cached at startup. Note that users can also block DMs from server members, which returns error 50007 with no workaround.

At 100 servers. Beyond that, privileged intents require verification, which is a manual review - apply early, because a bot that reaches 100 servers unverified loses privileged intents and goes silent for its entire user base at once. Separately, bots in 2,500 or more guilds must implement sharding.

It is responding to its own messages. Add `if (message.author.bot) return;` as the first line of your message handler. Without that guard a bot replies to its own reply indefinitely until Discord rate limits it, and two unguarded bots in one channel will generate thousands of messages in seconds.

About the Author

Content & Engineering

The Conferbot team writes about building, deploying, and improving AI chatbots.

View all articles
Skip the blank canvas
Start from one of 250+ free chatbot templates for lead generation, support, e-commerce, and 20+ industries - customize and launch in minutes.
Browse free templates

Related Articles

Omnichannel Platform

One Chatbot,
Every Channel

Your chatbot works seamlessly across WhatsApp, Messenger, Slack, and 6 more platforms. Build once, deploy everywhere.

View All Channels
Conferbot
online
Hi! How can I help you today?
I need pricing info
Conferbot
Active now
Welcome! What are you looking for?
Book a demo
Sure! Pick a time slot:
#support
Conferbot
New ticket from Sarah: "Can't access dashboard"
Auto-resolved. Password reset link sent.