NapNodes

← Discord bot guides

Discord bots · updated 24 October 2026

Your Discord bot token: where to keep it and what to do if it leaks

The token is your bot's password: whoever has it can log in as the bot and do on your servers everything the bot is allowed to do. It almost always leaks the same way, pushed to GitHub by accident, and it's always fixed the same way: by getting a new one. Here's how to keep it safe and what to do, in order, if it's already too late.

What the token is (and what it isn't)

You get it at discord.com/developers/applications, in your application → “Bot” → “Reset Token”, and it's a long string in three parts separated by dots. Your code hands it to Discord when it connects (client.run in discord.py, client.login in discord.js) and Discord asks for nothing else: not your password, not your two-factor code.

Don't confuse it with the “Client Secret” on the “OAuth2” tab: that one is for websites that log in with Discord, it's shorter and a bot won't start with it. Nor with the “Application ID”, which is public (it goes in the invite link).

There's another string that's just as secret even if it doesn't look like it: a webhook URL (https://discord.com/api/webhooks/…). Whoever has it can post in that channel with any name and picture they like. Treat it like the token.

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.

Where to keep it: a .env that never goes to GitHub

The safe way is for the token not to be in the code: in a separate .env file the bot reads at startup (with python-dotenv in Python and dotenv in Node.js, as in your first bot in Python or in JavaScript), plus a .gitignore that tells Git never to push it.

.env
DISCORD_TOKEN=paste-your-token-here
.gitignore
.env
node_modules/
__pycache__/
.venv/
  1. Create the .gitignore before the first commit

    If the .env was pushed once, adding it to .gitignore afterwards doesn't remove it: Git keeps tracking it. Take it out with git rm --cached .env, commit and, since it was already public, change the token (below).

  2. Check what you're about to push

    git status before every commit: if .env is on the list, stop. On GitHub, check the file doesn't show up on the repository page.

  3. Leave an example without the token

    A .env.example with an empty DISCORD_TOKEN= tells anyone using your code what to fill in, without giving away yours.

How it leaks (almost always)

Pushed to a public GitHub repository, in the code or in the .env. It's by far the most common way, and GitHub detects it: it scans public code for Discord tokens and tells Discord, which can revoke it. If one day your bot stops connecting with “Improper token has been passed” (discord.py) or “TokenInvalid” (discord.js) and you had just pushed something, this is almost certainly why: check your Discord direct messages and your email.

Deleting it in a new commit doesn't help: it's still in the history, and anyone who cloned or forked it has it. It doesn't matter if the repository was public for five minutes: there are programs that read everything published on GitHub looking for tokens.

The other ways: a screenshot of your code or your .env when asking for help, pasting the whole code in a forum or a Discord server, or installing a fake package. Packages with names close to the real ones turn up on PyPI and npm from time to time, looking for tokens on your computer and sending them off: install libraries by their exact name (discord.py, discord.js) and distrust “tools” that ask for your token to do something for you.

It leaked: what to do, in this order

  1. Change the token now

    Developer portal → your application → “Bot” → “Reset Token”. The old one stops working at that moment, wherever it is. It's the only thing that really fixes it; everything else is cleaning up. If you have two-factor authentication on, Discord will ask for the code.

  2. Put the new one in your .env and restart the bot

    The token is only read at startup: until you restart, your bot keeps trying to log in with the old one.

  3. Remove the old one from where it was

    From the code, from the .env you pushed (git rm --cached .env and commit) and from wherever you pasted it. Rewriting Git history is optional: the old one no longer works, so what matters is that the new one doesn't go the same way.

  4. See what the bot has done

    On every server it's in, “Server Settings” → “Audit Log”, filtering by your bot: deleted channels, changed roles, kicked members or mass messages. If someone used it, it shows there, and the messages it sent are still in the channels.

  5. Review the application

    In the portal: that “Public Bot” is set the way you want (if it's on, anyone can add your bot to their server), that the team (“Teams”) that manages it has nobody extra and that the “OAuth2” and webhook URLs are yours.

  6. If there were webhooks in the code, change them too

    Resetting the bot token doesn't fix a webhook: delete it in “Edit Channel” → “Integrations” → “Webhooks” and create another.

Making a stolen token do as little harm as possible

Whoever has the token can do exactly what the bot is allowed to do, no more, no less. A stolen bot with “Administrator” can wipe the whole server; one that can only read and write in two channels, little more than send messages. Give it only the permissions it uses: with the bot permissions calculator you tick the ones it needs and get the invite link with just those.

Same with the privileged intents (members, presence and message content): turn them on in the portal only if your code uses them (what each one does and which you need).

And if the bot is only for your server and your friends, turn off “Public Bot”: that way nobody else can add it to other servers under your name.

If your bot is on NapNodes

The token goes in your code, for example in the .env, never in the panel: the panel has no field for it and doesn't need it. If you upload your code in “Files”, upload the .env with it. If you pull it from GitHub (“Settings” → “GitHub repository”), the .env isn't in the repository (because of the .gitignore), so upload it separately in “Files”: when pulling changes from the repository, Git doesn't touch files it doesn't track.

If your repository is private, the panel asks for a username and a “GitHub token”: that's a different token, from GitHub, not the Discord one. The safest is a fine-grained one (Settings → Developer settings → Fine-grained tokens) for that repository only and with read-only access to contents: that's all it needs to download the code.

After changing the token, upload it to the .env in “Files” and press “Restart”: the “Console” should show your “Logged in as…”. If you have nowhere to host it, there's a free 256 MB bot that stays online, which you only have to renew with one click every week.

Frequently asked questions

What happens if someone has my bot's token?

They can log in as your bot and do everything the bot is allowed to on your servers: send messages, delete channels or kick people if it has those permissions. Change the token in the developer portal (“Bot” → “Reset Token”) and the old one stops working instantly.

I pushed my bot token to GitHub, what do I do?

Change it now in the developer portal (“Bot” → “Reset Token”), put the new one in your .env and restart the bot. Deleting it from the repository isn't enough: it's still in the history. GitHub tells Discord about tokens that appear in public code, so it may already have been revoked.

Why does my Discord bot stop working with “Improper token has been passed”?

Because the token your code reads is no longer valid: you changed it in the portal, it leaked and Discord revoked it, or the .env isn't read properly (spaces, quotes, a different name). Get a new one with “Reset Token” and restart.

Is the Client Secret the bot token?

No. The Client Secret (“OAuth2” tab) is for websites that log in with Discord. The bot token is on the “Bot” tab and is much longer, in three parts separated by dots.

Where do I keep my Discord bot token?

In a .env file your bot reads at startup, with .env in the .gitignore so it never goes to GitHub. Never written in the code or in screenshots you share.

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 →