siyuan-note/siyuan · error

parse font failed: %v

Error message

parse font failed: %v

What it means

Returned by parseCustomFontFile from its deferred recover() when the sfnt parser (golang.org/x/fonts/sfnt via ConradIrwin/font) panics while reading the font. The panic value is formatted with %v and wrapped as 'parse font failed: <value>'. This is a safety net around a third-party library that panics on malformed input.

Source

Thrown at kernel/util/custom_font.go:323

		return ".otf", nil
	default:
		return "", errors.New("only TTF and OTF font files are supported")
	}
}

func customFontHash(reader io.Reader) (string, error) {
	hash := sha256.New()
	if _, err := io.Copy(hash, reader); err != nil {
		return "", err
	}
	return hex.EncodeToString(hash.Sum(nil)), nil
}

func parseCustomFontFile(fontFile *os.File) (ret *Font, err error) {
	defer func() {
		if recovered := recover(); recovered != nil {
			ret = nil
			err = fmt.Errorf("parse font failed: %v", recovered)
		}
	}()

	parsed, err := sfnt.Parse(fontFile)
	if err != nil {
		return nil, fmt.Errorf("parse font failed: %w", err)
	}
	ret, err = parseFontInfo(parsed)
	if err != nil {
		return nil, fmt.Errorf("parse font metadata failed: %w", err)
	}
	return ret, nil
}

func validCustomFontID(id string) bool {
	if len(id) != sha256.Size*2 || strings.ToLower(id) != id {
		return false
	}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Re-download or replace the font file — it is corrupt and cannot be installed.
  2. Validate the font with an external tool (fonttools, otfproof, or FontForge) before uploading to identify the broken table.
  3. If the panic is reproducible from a legitimate file, report it upstream to the sfnt parser with the triggering file.
Defensive patterns

Strategy: try-catch

Try / catch

if _, _, err := util.InstallCustomFont(tempPath); err != nil {
    if strings.Contains(err.Error(), "parse font failed") {
        // corrupt font: ask the user for a fresh copy
    }
}

Prevention

When it happens

Trigger: InstallCustomFont or loadCustomFontsLocked passes a font file that passes the magic-byte check but is structurally malformed enough to make the sfnt parser panic during table parsing.

Common situations: A deliberately fuzzed or corrupted font; a font where required tables (head, name, OS/2) are missing or truncated; a font that survived the 4-byte header check but is otherwise garbage.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/3c540964a55dc789. Report an issue: GitHub.