Why Discord Webhook Username Sanitization Removes Specific Unicode
🔍 WiseChecker

Why Discord Webhook Username Sanitization Removes Specific Unicode

When you send a message via a Discord webhook, you might notice that certain Unicode characters in the username field get silently removed or replaced. This happens even when the same characters work fine in a regular Discord user or bot username. The symptom is a username that looks incomplete or has unexpected gaps. The cause is Discord’s server-side sanitization that strips characters it considers unsafe or incompatible with its username validation rules. This article explains exactly which Unicode characters are removed, why Discord applies this filtering, and how to work around the limitation without breaking your webhook integrations.

Key Takeaways: Discord Webhook Username Unicode Filtering

  • Zero-width and control characters (U+200B, U+200C, U+200D, U+FEFF): These are always stripped because they have no visible glyph and can be used for spoofing or hidden text.
  • Surrogate pairs and invalid UTF-8 sequences: Discord rejects malformed Unicode that doesn’t conform to UTF-8 encoding standards, causing the entire username to be rejected or truncated.
  • Characters outside Basic Multilingual Plane (BMP) above U+FFFF: Emoji and rare scripts like Linear B may be removed because Discord’s username field only accepts characters from the BMP for webhooks.

ADVERTISEMENT

How Discord Sanitizes Webhook Usernames

Discord applies a two-stage filtering process to webhook usernames. The first stage runs on the client side or API layer before the webhook payload is sent to Discord’s servers. The second stage happens on the server side when Discord processes the message. The server-side filter is stricter than the client-side one.

The username field in a webhook payload is a string with a maximum length of 80 characters. Discord’s API documentation states that usernames must contain only valid UTF-8 characters. But in practice, Discord’s implementation goes further by removing characters that could cause rendering issues, security exploits, or compatibility problems across different platforms and devices.

Characters That Are Always Removed

Discord strips the following categories of Unicode characters from webhook usernames:

  • Zero-width characters: U+200B (zero-width space), U+200C (zero-width non-joiner), U+200D (zero-width joiner), U+FEFF (byte order mark / zero-width no-break space). These characters have no visible representation and are removed to prevent hidden text or spoofing.
  • Control characters: U+0000 through U+001F and U+007F through U+009F. These include tab, carriage return, and other non-printable codes. Discord removes them to avoid disrupting message formatting or client rendering.
  • Surrogate halves: U+D800 through U+DFFF. These are invalid in UTF-8 and are never present in a properly encoded string. If sent, Discord rejects the entire webhook request with a 400 error.
  • Non-BMP characters: Characters above U+FFFF, including most emoji and rare scripts. Discord’s webhook username field is limited to the Basic Multilingual Plane. Sending emoji like 😀 (U+1F600) results in the emoji being removed or the username being truncated.

Why Discord Applies These Restrictions

Discord’s sanitization exists to prevent several real problems. Zero-width characters can be used to insert hidden text that appears as normal spaces, enabling impersonation or bypassing word filters. Control characters can crash or confuse clients that don’t handle them properly. Non-BMP characters like emoji cause rendering inconsistencies across devices and platforms, especially in places like the member list or direct messages where the username is displayed in a small font.

The sanitization is also a security measure. Malformed UTF-8 sequences can trigger buffer overflows or injection attacks in older client versions. By aggressively filtering the username field, Discord reduces the attack surface for webhook integrations, which are often used by third-party services that may not validate input properly.

Steps to Test Which Characters Get Removed

  1. Create a test webhook in a private channel
    Go to Server Settings > Integrations > Webhooks. Click New Webhook, give it a name, and copy the webhook URL. Use a channel where only you can see the messages to avoid spamming others.
  2. Send a webhook with a known problematic character
    Use a tool like curl, Postman, or a simple Python script to POST to the webhook URL. Set the username field in the JSON payload to a string that includes a zero-width space (U+200B) or an emoji (U+1F600). Example payload: {"username": "Test\u200BUser", "content": "Checking sanitization"}
  3. Inspect the resulting username in Discord
    Look at the message in the channel. If the character was removed, the username will appear as “TestUser” without any visible gap. If the character caused a rejection, you’ll see a 400 Bad Request error in your HTTP response.
  4. Repeat with other characters
    Test each category: control characters (U+000A for newline), surrogate halves (U+D800), and non-BMP characters (U+1F600). Log the results to confirm which ones are stripped versus which cause a full rejection.

ADVERTISEMENT

If Discord Still Removes Characters After Testing

Webhook Username Appears Truncated After Emoji

If you include an emoji in the username, Discord may remove it and also truncate the rest of the username after that point. This happens because Discord’s sanitizer processes the string left to right and stops when it encounters a non-BMP character. The fix is to place emoji only at the end of the username, or avoid them entirely. Use text-based alternatives like :smile: in the content field instead.

Webhook Request Returns 400 Bad Request

A 400 error means the payload contains invalid UTF-8 or a surrogate half. Check your encoding. Ensure the JSON payload is UTF-8 encoded and that the username string does not contain any lone surrogates. Python developers should use json.dumps() with ensure_ascii=False to preserve Unicode characters properly. If you’re manually constructing the JSON, validate it with a tool like JSONLint before sending.

Username Shows as Blank After Sanitization

If every character in your username is removed by Discord’s filter, the webhook will fall back to the default name “Webhook” or the webhook’s saved name in server settings. To avoid this, always include at least one visible ASCII character (a letter, number, or punctuation) in the username. For example, use “BotName” instead of a string of zero-width spaces.

Character Category Example Code Point Discord Behavior
Zero-width space U+200B Silently removed
Control character (tab) U+0009 Silently removed
Surrogate half U+D800 Rejects entire request with 400 error
Emoji (non-BMP) U+1F600 Silently removed, may truncate subsequent characters
Latin letter A U+0041 Allowed without modification

Discord’s webhook username sanitization is a deliberate design choice that prioritizes security and compatibility over flexibility. Understanding exactly which characters are removed helps you build webhook integrations that work reliably across all clients and platforms. The safest approach is to limit webhook usernames to ASCII letters, numbers, and common punctuation. If you need special characters, place them at the end of the string and test with your specific Discord client version. For advanced use cases like dynamic usernames from external systems, consider using Discord’s application command system instead, which supports a wider range of Unicode characters in display names.

ADVERTISEMENT