siyuan-note/siyuan · error

only TTF and OTF font files are supported

Error message

only TTF and OTF font files are supported

What it means

Returned by detectCustomFontExtension when the 4-byte magic header does not match any supported signature. Accepted magics are \x00\x01\x00\x00 and 'true' (TTF) and 'OTTO' (OTF). WOFF, WOFF2, EOT, and other container formats are rejected even though their payload may contain TTF/OTF data.

Source

Thrown at kernel/util/custom_font.go:307

		if _, active := customFontTemps[tempPath]; !active {
			_ = os.Remove(tempPath)
		}
	}
}

func detectCustomFontExtension(reader io.Reader) (string, error) {
	header := make([]byte, 4)
	if _, err := io.ReadFull(reader, header); err != nil {
		return "", errors.New("font file is invalid")
	}

	switch string(header) {
	case "\x00\x01\x00\x00", "true":
		return ".ttf", nil
	case "OTTO":
		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)
		}
	}()

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Convert the font to a plain TTF or OTF before uploading (e.g. fonttools pyftfontforge, or download the TTF/OTF variant directly).
  2. Re-download from the source choosing the .ttf or .otf file rather than .woff/.woff2.
  3. Verify the file is actually a font and not a renamed archive or image.

Example fix

// before
util.InstallCustomFont(tempPath) // tempPath holds a .woff

// after
// convert first:  pyftsubset font.woff --output-file=font.ttf
// or download the TTF variant, then:
util.InstallCustomFont(tempPathTTF)
Defensive patterns

Strategy: validation

Validate before calling

func supportedFontMagic(header []byte) bool {
    switch string(header[:4]) {
    case "\x00\x01\x00\x00", "true", "OTTO": return true
    }
    return false
}

Prevention

When it happens

Trigger: Calling InstallCustomFont with a font whose first 4 bytes are not the TTF/OTF signature — typically WOFF (magic 'wOFF'), WOFF2 ('wOF2'), EOT, or a non-font file that happens to be at least 4 bytes.

Common situations: A user downloaded a WOFF/WOFF2 web font (common from Google Fonts) and tried to install it directly; a variable font packaged in a container format; a renamed non-font file with a .ttf extension.

Related errors


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