{"record":{"id":"04aaef394f7d92f3","repo":"siyuan-note/siyuan","slug":"font-file-is-too-large","errorCode":null,"errorMessage":"font file is too large","messagePattern":"font file is too large","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/util/custom_font.go","lineNumber":109,"sourceCode":"\tdefer customFontsLock.Unlock()\n\n\tloadCustomFontsLocked()\n\treturn cloneCustomFonts(customFonts)\n}\n\nfunc InstallCustomFont(tempPath string) (*CustomFont, bool, error) {\n\tcustomFontsLock.Lock()\n\tdefer customFontsLock.Unlock()\n\n\tinfo, err := os.Stat(tempPath)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\tif !info.Mode().IsRegular() || info.Size() < 1 {\n\t\treturn nil, false, errors.New(\"font file is empty\")\n\t}\n\tif MaxCustomFontSize < info.Size() {\n\t\treturn nil, false, errors.New(\"font file is too large\")\n\t}\n\n\tfontFile, err := os.Open(tempPath)\n\tif err != nil {\n\t\treturn nil, false, err\n\t}\n\n\textension, err := detectCustomFontExtension(fontFile)\n\tif err != nil {\n\t\tfontFile.Close()\n\t\treturn nil, false, err\n\t}\n\tif _, err = fontFile.Seek(0, io.SeekStart); err != nil {\n\t\tfontFile.Close()\n\t\treturn nil, false, err\n\t}\n\n\tid, err := customFontHash(fontFile)","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/custom_font.go#L91-L127","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nfont, installed, err := util.InstallCustomFont(tempPath)\n// after\nif info, err := os.Stat(tempPath); err == nil && info.Size() > util.MaxCustomFontSize {\n    return fmt.Errorf(\"font exceeds %d bytes; subset or compress it\", util.MaxCustomFontSize)\n}\nfont, installed, err := util.InstallCustomFont(tempPath)","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(tempPath); err == nil && info.Size() > util.MaxCustomFontSize {\n    return fmt.Errorf(\"font too large: %d > %d\", info.Size(), util.MaxCustomFontSize)\n}","typeGuard":null,"tryCatchPattern":"font, _, err := util.InstallCustomFont(tempPath)\nif err != nil && err.Error() == \"font file is too large\" {\n    // surface a subset-the-font message to the user\n}","preventionTips":["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"],"tags":["validation","file-size-limit","custom-font"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}