siyuan-note/siyuan · warning
avif: exif data too short
Error message
avif: exif data too short
What it means
parseExifData rejects EXIF payloads shorter than the 8-byte TIFF header (byte-order marker + magic + IFD offset). An EXIF item in the HEIF container must at minimum contain that header; anything shorter cannot be parsed. This is a malformed-metadata condition, not a decode failure of the image pixels.
Source
Thrown at kernel/heif/internal/h265heic/exif.go:273
return string(r.data[offset:end])
}
func (r *exifReader) readRational(offset int) float64 {
if offset < 0 || offset+7 >= len(r.data) {
return 0
}
num, den := r.uint32(offset), r.uint32(offset+4)
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")View on GitHub (pinned to 8641553a1f)
Solutions
- Treat EXIF as absent and continue — the image itself may still decode fine
- Verify the Exif item offset/length extraction from the meta box is correct (off-by-N slicing is the usual culprit)
- Re-export the photo with EXIF intact if orientation/GPS metadata matters
- If you produce these containers, validate that item extents are non-empty before writing
Example fix
// before
exif, err := h265heic.DecodeExif(f)
if err != nil {
return fmt.Errorf("exif: %w", err)
}
// after
exif, err := h265heic.DecodeExif(f)
if err != nil {
// malformed/absent EXIF must not block image display
exif = nil
} Defensive patterns
Strategy: fallback
Validate before calling
if exifItem != nil && len(exifItem.Data) < 8 {
log.Warn("EXIF item payload too short; treating as absent")
exifItem = nil
} Type guard
func hasValidExifHeader(data []byte) bool {
return len(data) >= 8 && (data[0] == 'I' || data[0] == 'M') && (data[1] == 'I' || data[1] == 'M')
} Try / catch
exif, err := h265heic.DecodeExif(f)
if err != nil {
log.Debugf("EXIF unavailable: %v", err)
exif = h265heic.DefaultExif() // orientation 1, no GPS
} Prevention
- Never let EXIF parse failures block image display — degrade to defaults
- Validate item extent lengths in the meta box before slicing payloads
- Assume camera/tool output may strip EXIF and handle its absence everywhere
- Verify offset extraction skips any container-added prefix bytes
When it happens
Trigger: DecodeExif called on a HEIF/AVIF whose Exif item payload is truncated (0-7 bytes), e.g. the extractor sliced at the wrong offset or the file's meta box declares an Exif item with an empty/tiny body.
Common situations: Files edited by tools that strip EXIF but keep the item entry; incorrect item-offset extraction producing a zero-length slice; hand-crafted or fuzzed containers.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- avif: invalid exif byte order marker
- avif: invalid exif magic number
- avif: invalid exif ifd offset
- invalid bazaar index generation metadata
- encrypted HEIF cache requires a notebook ID
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/cbf8dfa228b5f468.
Report an issue: GitHub.