Inside the RestoreCord verification callback
Everything that decides whether a member gets their role happens in one server-side request: the redirect back from Discord. Read the stages in order and every verify-page error code starts to make sense.
Short answer
After Discord redirects back, RestoreCord swaps the code for tokens, looks up the IP, runs your firewall rules, then captcha, alt, cellular and account-age checks unless a Bypass All rule matched. Only then does it add the member with guilds.join and apply roles. Each stage has its own error codes.
Before any check runs
The callback first makes sure the request is real. A missing code or state returns 10401, and a member who pressed Cancel on Discord's screen gets 990049 with a plain instruction to try again and click Authorize. Next it loads the server named in state and the bot attached to it, then exchanges the code for tokens using that bot's client credentials.
- Unknown server in state: 10004
- Bot record missing: 10002
- Discord rejects the bot's client ID or secret: 10005
- Token exchange succeeds but Discord returns no usable user: 10001
None of these involve your rules yet. If a member hits one, the fix almost always lives in the bot or server setup, which is why the page tells them to contact the owner or simply try again.
The decision order
Once the member is known, the checks run in a fixed sequence. The order matters: an earlier stage can end the request before a later one is ever evaluated.
- IP lookup: one resolution supplies country, continent, ASN, connection type and the VPN or proxy flag
- Firewall rules: targets include user ID, username, role, IP, IP range, country, continent, ASN, email domain, server membership and time
- Password: a Require Password decision asks for the server's verification password, or reads it from the link
- Captcha, when the server turns it on
- Alt match against the same server's earlier IPs and visitor IDs
- Cellular block and minimum account age, on Enterprise
- The add-member call, then the verified, unverified and Give Role effects
A rule with the Bypass All action skips captcha, alt matching, the cellular block and account age for whoever it matches. Scope it to specific user IDs or roles, never to a whole country or ASN.
Error codes by stage
| Code | Stage | Usually fixed by |
|---|---|---|
| 990031 | A firewall rule blocked the member | Owner, if the rule is too broad |
| 990044 / 990046 | VPN or proxy, or a blocked server membership | Member, by changing connection or leaving |
| 990048 | Email required but the scope was unticked | Member, by keeping Email enabled |
| 990034 | The IP lookup or role check was unavailable | Nobody: retry shortly |
| 990045 | Alt match with Block Alts on | Owner review of the match |
| 990043 / 990035 | Cellular block, or account below minimum age | Member: other network, or wait |
| 10003 | Discord rate-limited the account or bot | Time: wait 60 minutes |
| 10013 | Discord restricts the account from joining servers | Member, in their Discord account |
| 990047 | Server invites are disabled | Owner, in Server Settings |
| 50013 / 990403 / 990404 | Bot can't assign the verified role, or the role is gone | Owner: role order and permissions |
After the member is added
A successful add-member response is when the member record is written with the tokens, IP details as allowed by your logging setting, and the tracking-link code from state. Roles are applied next. Then the verify page posts the browser visitor ID, described in alt detection signals.
Denials are not silent. Every stage that turns someone away can post to your webhook log, and on Enterprise a signed member-denied event carries the reason so your own systems can react.
Related
Why 10003 happens and how long it lasts is covered in rate limits. Which scopes land in the token is explained in OAuth2 scopes. Or go back to the under-the-hood overview.
Before you blame the firewall
Most role failures are configuration, not rules. Check these first.
Bot role sits above the verified role
Discord refuses to assign a role higher than the bot's own, which surfaces as 50013 or 990403.
Verified role still exists
A deleted or recreated role has a new ID, so the old setting points nowhere and returns 990404.
Invites are enabled
With server invites paused, Discord won't let the bot add anyone and the page shows 990047.
Bot token is current
A token reset in the Developer Portal breaks verification until the new one is saved in RestoreCord.
No over-wide Bypass All rule
If alts are slipping through, check that no bypass rule matches far more people than intended.
Test from a spare account
After every change, verify once yourself so you see exactly what members see.
Trace a failed verification
Note the code
Ask the member for the number shown on the verify page instead of a screenshot of the whole flow.
Find the stage
Look the code up in the table above to see whether Discord, the firewall or your bot setup produced it.
Fix the right layer
Change the rule, the role order or the bot token, then verify again from a spare account to confirm.
Callback questions
Rules that run in the order you expect
Build firewall rules, watch the decisions in your logs and keep the codes on this page close by.