Discord error 4004: Authentication failed
Last verified against Discord Developer Docs - Opcodes and status codes
The account token sent with your identify payload is incorrect.What error 4004 means
The token in your Identify payload is wrong, and Discord has closed the connection. This is the gateway equivalent of 50014 on REST, and it is the number-one reason a bot shows as offline. Nothing about intents, permissions or code logic matters at this point; the token is rejected before any of that.
Discord marks 4004 as not reconnectable. Libraries honor that by throwing (discord.js: Error [TokenInvalid]; discord.py: LoginFailure: Improper token has been passed) rather than retrying, which is correct: the same token will fail forever. If you wrap the login in a retry loop, every attempt is counted as an invalid request and you will be temporarily banned from the API.
Tokens become wrong in three ways: they were never right (typo, partial paste, wrong secret copied), they were reset in the Developer Portal (Reset Token), or Discord revoked them after detecting them in a public place such as a pushed repository.
What it looks like
// WebSocket close frame
code: 4004
reason: "Authentication failed."
// discord.js
Error [TokenInvalid]: An invalid token was provided.
// discord.py
discord.errors.LoginFailure: Improper token has been passed.Why it happens
- Token reset in Developer Portal; deployed config still holds the old value
- Token leaked publicly and auto-revoked
- Environment variable empty or holding the client secret / public key instead of the bot token
- Trailing whitespace, quotes or newline included in the token string
- Token from a different application (dev vs prod mix-up)
- Sending a user account token as a bot (self-bots are not supported and violate the ToS)
How to fix Discord error 4004
- 1Developer Portal > Applications > your app > Bot > Reset Token; copy once and update your secret store
- 2Verify with curl -H "Authorization: Bot $TOKEN" https://discord.com/api/v10/users/@me before starting the bot
- 3Strip whitespace when reading the env var and assert it is non-empty at startup
- 4Check you are loading the right env file for the environment (dev vs prod)
- 5Remove any retry loop around login; exit with a clear message on 4004
How to stop it recurring
Keep the token in a secrets manager, never in source, and add a secret scanner to CI. Use separate applications for development and production with clearly named variables. Add a health check at startup that calls GET /users/@me and refuses to boot on 401 so the failure is loud and immediate. See Discord bot not responding for the full offline-bot checklist.
Official reference: Discord Developer Docs - Opcodes and status codes. See all Discord error codes or the Discord limits and quotas.
Related codes
- 50014: Invalid authentication token providedInvalid authentication token provided
- 40001: UnauthorizedUnauthorized. Provide a valid token and try again
- 4014: Disallowed intent(s)You sent a disallowed intent for a Gateway Intent. You may have tried to…
- 4003: Not authenticatedYou sent us a payload prior to identifying, or this session has been…
Error 4004 - quick answers
What does Discord error 4004 mean?
The token in your Identify payload is wrong, and Discord has closed the connection. This is the gateway equivalent of 50014 on REST, and it is the number-one reason a bot shows as offline. Nothing about intents, permissions or code logic matters at this point; the token is rejected before any of that. Discord marks 4004 as not reconnectable .
How do I fix Discord error 4004?
1. Developer Portal > Applications > your app > Bot > Reset Token; copy once and update your secret store 2. Verify with curl -H "Authorization: Bot $TOKEN" https://discord.com/api/v10/users/@me before starting the bot 3. Strip whitespace when reading the env var and assert it is non-empty at startup 4. Check you are loading the right env file for the environment (dev vs prod) 5. Remove any retry loop around login; exit with a clear message on 4004
Stop debugging Discord by hand
Connect the channel through Conferbot: tokens, webhooks and retries are handled, failures show as readable status.