siyuan-note/siyuan · error
invalid custom emoji image
Error message
invalid custom emoji image
What it means
Returned by normalizeCustomEmojiData for raster images (png/jpeg/gif/webp detected by http.DetectContentType) when image.DecodeConfig fails OR the dimensions are invalid: width or height < 1, either side > 16384 px, or width*height > 100,000,000 pixels. The bytes smelled like a raster image but are corrupt or absurdly large.
Source
Thrown at kernel/api/system.go:375
raster := true
switch http.DetectContentType(data) {
case "image/png":
ext = ".png"
case "image/jpeg":
ext = ".jpg"
case "image/gif":
ext = ".gif"
case "image/webp":
ext = ".webp"
default:
raster = false
}
if raster {
config, _, decodeErr := image.DecodeConfig(bytes.NewReader(data))
if decodeErr != nil || config.Width < 1 || config.Height < 1 || config.Width > 16384 || config.Height > 16384 ||
int64(config.Width)*int64(config.Height) > 100*1000*1000 {
return nil, "", fmt.Errorf("invalid custom emoji image")
}
return data, ext, nil
}
sanitizedSVG, sanitizeErr := util.SanitizeSVG(string(data))
if sanitizeErr == nil {
return []byte(sanitizedSVG), ".svg", nil
}
return nil, "", fmt.Errorf("unsupported custom emoji image format")
}
func normalizeCustomEmojiPath(name, ext string) (string, error) {
name = strings.TrimSpace(strings.ReplaceAll(name, "\\", "/"))
parts := strings.Split(name, "/")
if len(parts) == 0 {
return "", fmt.Errorf("custom emoji name must not be empty")
}
View on GitHub (pinned to 251596fc0d)
Solutions
- Re-open the file in an image editor and re-export to confirm it is a valid image.
- Downscale so neither side exceeds 16384 px and total pixels stay under 100M.
- Verify the file with `file icon.png` and `identify icon.png` (ImageMagick) before uploading.
- If the file is valid but exotic (e.g. AVIF/HEIC), convert to png/webp first; those formats are not in the accepted set.
Example fix
// before // uploading a truncated 20000x20000 png -> 'invalid custom emoji image' // after: validate locally first // identify icon.png # confirm dimensions are sane and body is complete // convert icon.png -resize 512x512 icon_small.png // then upload icon_small.png
Defensive patterns
Strategy: validation
Validate before calling
// Validate raster dimensions locally before uploading
cfg, _, err := image.DecodeConfig(f)
if err != nil { return fmt.Errorf("not a decodable image: %w", err) }
if cfg.Width < 1 || cfg.Height < 1 { return errors.New("invalid dimensions") }
if cfg.Width > 16384 || cfg.Height > 16384 { return errors.New("dimension exceeds 16384px") }
if int64(cfg.Width)*int64(cfg.Height) > 100_000_000 { return errors.New("pixel count exceeds 100M") } Prevention
- Re-export images through an editor to confirm body integrity.
- Cap dimensions at 512-1024px for emoji use.
- Verify with `identify`/`file` before uploading.
When it happens
Trigger: Uploading a truncated PNG/GIF (headers intact, body cut off so DecodeConfig fails), a deliberately huge dimension image (>16384 px), or a file with a spoofed extension whose magic bytes match a raster type but the body is malformed.
Common situations: Partial download saved as an image; a screenshot exported at extreme resolution; a file renamed .png but actually a different binary; a JPEG with only SOI marker.
Related errors
- custom emoji file is too large
- custom emoji file must not be empty
- unsupported custom emoji image format
- custom emoji name must not be empty
- invalid custom emoji name
AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12).
Data as JSON: /api/errors/3cf2ee986131688d.
Report an issue: GitHub.