Discord Webhook Errors: 400, 401, 403, 404, 429 — Causes & Fixes
Every common Discord webhook error explained: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Unknown Webhook, and 429 rate limits — with exact causes and fixes.
🇷🇺 Also available in Русский
Discord Webhook Not Working? Start Here
When a webhook fails, Discord returns an HTTP status code and usually a JSON error body with a code and message. Reading those two fields tells you exactly what’s wrong. This guide covers every status you’ll realistically hit, what causes it, and how to fix it.
First, a quick diagnostic. Run this from a terminal to see the raw status and message:
curl -i -H "Content-Type: application/json" \
-d '{"content": "test"}' \
"https://discord.com/api/webhooks/ID/TOKEN"
204 No Contentor200 OK→ the webhook works.- Anything else → match the code to the sections below.
400 — Bad Request (Invalid Form Body)
The most common error. Your JSON is malformed or breaks a Discord rule. The body usually looks like:
{ "message": "Invalid Form Body", "code": 50035, "errors": { ... } }
Causes and fixes:
- Broken JSON — a trailing comma, single quotes instead of double, or an unescaped quote. Validate the payload in a JSON linter first.
- Empty message — you must send at least one of
content,embeds, orfiles. An empty{}is rejected with code50006. contentover 2000 characters — split the message or move text into an embed description.- Embed limits exceeded — embed title ≤ 256, description ≤ 4096, max 25 fields, and a 6000-character total across all embeds. See the embed limits cheat sheet.
coloras a hex string — Discord wants a decimal integer (5763719), not"#57F287". See embed colors.- Wrong
Content-Type— sendapplication/json(ormultipart/form-datawhen uploading files).
The errors object pinpoints the exact field — read it carefully; it names the offending key.
401 — Unauthorized (Invalid Webhook Token)
{ "message": "Invalid Webhook Token", "code": 50027 }
The token portion of your webhook URL is wrong or no longer valid. This happens when:
- The webhook’s token was regenerated in Discord (Edit Webhook → the URL changed). Old URLs immediately stop working.
- You copied the URL incompletely or truncated the token.
- You accidentally sent an
Authorizationheader — webhook URLs authenticate via the token in the URL, so adding a bearer/bot token can cause conflicts. Don’t send one.
Fix: open the webhook in Server Settings → Integrations → Webhooks, click Copy Webhook URL, and use the fresh full URL.
403 — Forbidden
{ "message": "Missing Permissions", "code": 50013 }
The request reached Discord but isn’t allowed. Common causes:
- IP block — Discord blocks some hosting/datacenter IP ranges (notably Roblox game servers). Your code works locally but fails on the server. Route through a proxy — see sending webhooks from Roblox.
- Trying to mention
@everyonewithout permission, or pinging in a channel where the webhook lacks rights. - Posting to a thread the webhook can’t access, or a forum channel without a
thread_name. See threads and forums.
404 — Unknown Webhook
{ "message": "Unknown Webhook", "code": 10015 }
The webhook no longer exists. Unlike 401, this is permanent — there is no token to fix. It happens when:
- The webhook was deleted in Discord.
- The channel was deleted, which removes its webhooks.
- There’s a typo in the webhook ID (the numeric part of the URL).
Fix: create a new webhook and update your application with the new URL.
429 — Too Many Requests (Rate Limited)
{ "message": "You are being rate limited.", "retry_after": 1.5, "global": false }
You exceeded the webhook’s limit — roughly 30 requests per minute per webhook. The response includes retry_after (seconds to wait) and the X-RateLimit-* headers.
Fixes:
- Honor
retry_after— wait that many seconds, then retry. Never hammer in a tight loop. - Batch messages — combine many updates into one payload instead of one request each.
- Spread load — send different event types to separate webhooks in different channels.
Full strategies are in the rate limits guide.
Other Status Codes
| Code | Meaning | Fix |
|---|---|---|
405 Method Not Allowed | Wrong HTTP verb | Use POST to send, PATCH/DELETE to edit/delete |
413 Payload Too Large | File over the upload limit | Free webhooks allow 10 MB per request — compress or split |
500 / 502 / 503 | Discord-side outage | Transient — retry with backoff; check Discord status |
Quick Reference Table
| Status | Discord code | One-line cause | Fix |
|---|---|---|---|
| 400 | 50035 / 50006 | Malformed JSON or limits exceeded | Validate JSON, check embed limits |
| 401 | 50027 | Invalid/regenerated token | Copy a fresh webhook URL |
| 403 | 50013 | IP block or missing permission | Use a proxy / fix permissions |
| 404 | 10015 | Webhook or channel deleted | Create a new webhook |
| 429 | — | Rate limited | Honor retry_after, batch |
Preventing Errors Before You Send
The fastest way to avoid 400s entirely is to build and validate your payload visually. The free Discord Webhook Builder enforces every limit as you type and generates guaranteed-valid JSON, so you can copy a payload that’s correct on the first try. For programmatic sends, log the full response body — Discord’s message and code fields almost always name the exact problem.
Related Articles
- Discord Webhook Rate Limits Explained (429, Retry-After) — Deep dive on 429 handling
- Discord Embed Limits Cheat Sheet — Avoid 400s from oversized embeds
- Discord Webhook Security — Token Leaks & Rotation — What to do after a leak or token reset
- Edit and Delete Discord Webhook Messages — Correct PATCH and DELETE usage
Try it in our tool
Open Discord Webhook Builder