siyuan-note/siyuan · warning

avif: invalid exif byte order marker

Error message

avif: invalid exif byte order marker

What it means

The EXIF TIFF header's first two bytes must be the byte-order marker 'II' (little-endian) or 'MM' (big-endian). parseExifData found other bytes, meaning the payload is not a TIFF-style EXIF block. This usually indicates the wrong bytes were handed to the EXIF parser (offset error, or the payload is XMP/raw data instead of EXIF).

Source

Thrown at kernel/heif/internal/h265heic/exif.go:282

	if den == 0 {
		return 0
	}

	return float64(num) / float64(den)
}

func parseExifData(data []byte, exif *Exif) error {
	if len(data) < 8 {
		return errors.New("avif: exif data too short")
	}

	r := &exifReader{data: data}
	switch {
	case data[0] == 'I' && data[1] == 'I':
		r.littleEndian = true
	case data[0] == 'M' && data[1] == 'M':
	default:
		return errors.New("avif: invalid exif byte order marker")
	}

	if r.uint16(2) != 42 {
		return errors.New("avif: invalid exif magic number")
	}

	ifdOffset := r.uint32(4)
	if ifdOffset < 8 || int(ifdOffset) >= len(data) {
		return errors.New("avif: invalid exif ifd offset")
	}

	exifIFDOffset, gpsIFDOffset := parseIFD(r, int(ifdOffset), exif)
	if exifIFDOffset > 0 {
		parseExifSubIFD(r, exifIFDOffset, exif)
	}
	if gpsIFDOffset > 0 {
		parseGPSSubIFD(r, gpsIFDOffset, exif)
	}

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Inspect the first bytes of the payload; if it is XML it is XMP, not EXIF — parse with an XMP reader
  2. Check whether the container prepends an offset/length header to the EXIF item that must be skipped
  3. Treat the file as having no readable EXIF and fall back to defaults (orientation 1)
  4. Re-export the image from the original camera/software to regenerate standards-compliant EXIF

Example fix

// before
payload := itemData(exifItem) // includes 4-byte offset prefix
exif, err := parse(payload)   // -> invalid byte order marker
// after
payload := itemData(exifItem)
if len(payload) > 4 && payload[0] != 'I' && payload[0] != 'M' {
	payload = payload[4:] // skip TIFF-header offset prefix
}
exif, err := parse(payload)
Defensive patterns

Strategy: validation

Validate before calling

func hasTIFFByteOrderMark(data []byte) bool {
	return len(data) >= 2 && ((data[0] == 'I' && data[1] == 'I') || (data[0] == 'M' && data[1] == 'M'))
}

Type guard

func isExifPayload(b []byte) bool {
	return hasTIFFByteOrderMark(b)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "invalid exif byte order marker") {
	// payload is likely XMP or offset-prefixed; skip EXIF gracefully
	return nil, nil
}

Prevention

When it happens

Trigger: DecodeExif on a HEIF whose Exif item payload does not begin with 'II' or 'MM' — e.g. the parser was pointed at the item data including an offset skip it did not expect, or the item actually contains XMP or vendor blobs.

Common situations: Files where the EXIF item has a 4-byte offset prefix that was not skipped; cameras writing non-standard metadata items; mixing up XMP and Exif item indices when extracting from the meta box.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/f472af069b50f364. Report an issue: GitHub.