siyuan-note/siyuan · warning
font file is too large
Error message
font file is too large
What it means
InstallCustomFont enforces a hard size limit of MaxCustomFontSize (64 MiB) on custom font files. This error is thrown when the staged temp file exceeds that limit, protecting memory and disk from oversized font uploads.
Solutions
- Check the file size against util.MaxCustomFontSize before uploading/installing and reject early with a clear message
- Ask the user to subset the font (e.g. fonttools pyftsubset) to used glyphs to reduce size below 64 MiB
- Split or use a lighter weight/variant of the font family
- If the limit is genuinely too small for the product, raise MaxCustomFontSize (a code change, not a workaround at call time)
Example fix
// before
font, installed, err := util.InstallCustomFont(tempPath)
// after
if info, err := os.Stat(tempPath); err == nil && info.Size() > util.MaxCustomFontSize {
return fmt.Errorf("font exceeds %d bytes; subset or compress it", util.MaxCustomFontSize)
}
font, installed, err := util.InstallCustomFont(tempPath) Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(tempPath); err == nil && info.Size() > util.MaxCustomFontSize {
return fmt.Errorf("font too large: %d > %d", info.Size(), util.MaxCustomFontSize)
} Try / catch
font, _, err := util.InstallCustomFont(tempPath)
if err != nil && err.Error() == "font file is too large" {
// surface a subset-the-font message to the user
} Prevention
- Enforce the 64 MiB limit at upload time with a clear client-side message
- Subset large CJK fonts before distributing them
- Avoid installing .ttc collections; extract single faces
When it happens
Trigger: Calling InstallCustomFont(tempPath) where os.Stat reports info.Size() > 64*1024*1024 bytes — e.g. a huge font collection file (TTC), a font with embedded bitmaps, or an accidental upload of a non-font archive.
Common situations: Users trying to install very large CJK/pan-CJK fonts (often >64 MiB); uploading a .ttc collection or a renamed archive; backend accepting uploads without a client-side size check so the rejection happens only at install time.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/04aaef394f7d92f3.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/custom_font.go:109
defer customFontsLock.Unlock()
loadCustomFontsLocked()
return cloneCustomFonts(customFonts)
}
func InstallCustomFont(tempPath string) (*CustomFont, bool, error) {
customFontsLock.Lock()
defer customFontsLock.Unlock()
info, err := os.Stat(tempPath)
if err != nil {
return nil, false, err
}
if !info.Mode().IsRegular() || info.Size() < 1 {
return nil, false, errors.New("font file is empty")
}
if MaxCustomFontSize < info.Size() {
return nil, false, errors.New("font file is too large")
}
fontFile, err := os.Open(tempPath)
if err != nil {
return nil, false, err
}
extension, err := detectCustomFontExtension(fontFile)
if err != nil {
fontFile.Close()
return nil, false, err
}
if _, err = fontFile.Seek(0, io.SeekStart); err != nil {
fontFile.Close()
return nil, false, err
}
id, err := customFontHash(fontFile)View on GitHub (pinned to 9f775e8a12)