Discord Stickers Without the Upload Errors: 320 320 PNG, 512 KB, and What Actually Gets Rejected
I've been porting one set of stickers to every chat app that matters, and each one has its own rulebook. WhatsApp wanted 512×512 WebP under 100 KB. Telegram wanted a square canvas and a patient bot. I assumed Discord wou
I've been porting one set of stickers to every chat app that matters, and each one has its own rulebook. WhatsApp wanted 512×512 WebP under 100 KB. Telegram wanted a square canvas and a patient bot. I assumed Discord would be the easy one, because Discord feels casual. It rejected my first upload in under a second.
This post is the short version of what I learned: the exact spec, the emoji-vs-sticker confusion that trips everyone up, and the batch script I use now.
The spec, straight from Discord's docs
| Static sticker | Animated sticker | |
|---|---|---|
| Format | PNG | APNG |
| Dimensions | exactly 320×320 px | exactly 320×320 px |
| Max file size | 512 KB | 512 KB |
| Max length | — | 5 seconds |
(Lottie JSON exists too, but only verified and partnered servers can upload those. If you don't know whether your server is verified, it isn't.)
Slot counts are kinder than you'd expect. Every server gets 5 sticker slots for free, no boosts required. Boosting raises the ceiling: 15 slots at Level 1, 30 at Level 2, 60 at Level 3.
Sticker or emoji? They get confused constantly
Custom emojis are forgiving. Discord recommends 128×128 and 256 KB, but it quietly resizes whatever you give it. Upload something slightly wrong and it usually just works.
Stickers are the strict sibling. Exactly 320×320, no auto-resizing, and a vague "invalid file" when you miss. Two other fields matter more than they look:
- Name must be 2–30 characters.
- Related emoji is what Discord uses to surface your sticker in the suggestion picker. Pick one thoughtfully — it's the difference between your sticker appearing when someone needs it and your sticker never appearing at all.
Also: stickers belong to one server. To use them everywhere, you either need Nitro or you upload them again to each server.
The batch script: 512 master → 320 PNG
My masters are 512×512 WebP with transparency (the WhatsApp format from my earlier post), so Discord conversion is a straight resize:
from pathlib import Path
from PIL import Image
SRC = Path("masters") # 512x512 webp stickers
DST = Path("discord") # 320x320 png output
DST.mkdir(exist_ok=True)
for f in sorted(SRC.glob("*.webp")):
img = Image.open(f).convert("RGBA")
assert img.size == (512, 512), f"{f.name} is {img.size}"
out = img.resize((320, 320), Image.LANCZOS)
target = DST / (f.stem + ".png")
out.save(target, "PNG", optimize=True)
kb = target.stat().st_size / 1024
flag = "" if kb <= 512 else " <-- TOO BIG"
print(f"{f.name} -> {kb:.1f} KB{flag}")
Three details that matter:
-
convert("RGBA")— keep the alpha channel or your transparent background turns black. -
LANCZOS— at 320 px the wrong resampler visibly softens outlines. - The 512 KB budget is huge for flat art. Flat cartoon stickers land around 20–60 KB. Photographic or noisy art is the only thing that gets close to the limit.
If your source images aren't square yet, pad them onto a square canvas first — the padding trick is in the Telegram post.
Uploading
- Server Settings → Stickers (you need owner rights or the Manage Expressions permission).
- Upload Sticker, pick the 320 PNG.
- Fill the name (2–30 chars), the related emoji, and optionally a description — screen readers use it.
- Save. Everyone on the server can use it immediately.
What actually gets rejected
- 319 or 321 pixels. Unlike emoji upload, there is no auto-resize. "Exactly 320" is a border check, not a suggestion.
- GIF. The documented animated format is APNG. Don't rely on the client converting for you — convert it yourself.
- Over 5 seconds of animation. Trim it.
- Lottie files on a normal server. Partnered/verified only.
- Anything over 512 KB. With flat 320×320 art this basically doesn't happen; if it does, your art is too photographic for PNG and the fix is flattening the noise, not more compression.
The pattern across all three apps is the same, just with different numbers: WhatsApp is strictest about bytes, Telegram is strictest about the square, Discord is strictest about exact dimensions. Same art, three discipline problems.
If you'd rather skip the pipeline: FunnieStickers publishes every sticker with the Discord-ready 320 PNG next to the WhatsApp/Telegram WebP — the emoji set and the funny set are the ones my own server uses.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.