siyuan-note/siyuan · warning
avif: invalid exif ifd offset
Error message
avif: invalid exif ifd offset
What it means
The EXIF header's IFD offset field (at TIFF offset 4) must be at least 8 (past the header itself) and within the payload bounds. parseExifData read an offset pointing before the header or beyond the data, so the IFD (directory of tags) cannot be located. This indicates a corrupt or maliciously crafted EXIF block.
Source
Thrown at kernel/heif/internal/h265heic/exif.go:291
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)
}
return nil
}
// eachEntry walks the entries of an IFD, resolving each value to its offset.
func eachEntry(r *exifReader, offset int, fn func(tag, dataType uint16, count uint32, valueOffset int)) {
if offset < 0 || offset+1 >= len(r.data) {
return
}View on GitHub (pinned to 8641553a1f)
Solutions
- Check whether the writer used file-relative IFD offsets that need rebasing to the payload start
- Validate the payload is complete (compare item extent length against declared offsets) before parsing
- Treat EXIF as unreadable and render the image with default orientation
- Sanitize/strip EXIF and re-export the file if the source is untrusted
Example fix
// before
ifdOffset := r.uint32(4)
// after
ifdOffset := r.uint32(4)
// writers sometimes emit offsets relative to the TIFF header start; rebase
if ifdOffset < 8 && ifdOffset+8 < uint32(len(data)) {
ifdOffset += 8
} Defensive patterns
Strategy: validation
Validate before calling
func hasBoundedIFD(data []byte) bool {
if len(data) < 8 {
return false
}
r := newExifReader(data)
off := r.uint32(4)
return off >= 8 && int(off) < len(data)
} Type guard
func safeIFDOffset(data []byte) (int, bool) {
if len(data) < 8 {
return 0, false
}
off := int(binary.BigEndian.Uint32(data[4:8]))
if off < 8 || off >= len(data) {
return 0, false
}
return off, true
} Try / catch
if err != nil && strings.Contains(err.Error(), "invalid exif ifd offset") {
log.Warnf("EXIF IFD offset out of bounds; skipping metadata: %v", err)
return nil
} Prevention
- Bound-check every offset read from untrusted metadata before use
- Watch for writers using file-relative vs item-relative offset bases and rebase consistently
- Verify payload completeness (declared extents vs actual length) after sync/download
- Treat EXIF as optional metadata; never fail the image pipeline on its corruption
When it happens
Trigger: DecodeExif on a payload where the uint32 at offset 4 is < 8 or >= len(data) — truncated EXIF payloads where the header claims offsets into data that was cut off, or crafted values.
Common situations: Truncated sync/download cutting the EXIF payload after the header; writers emitting offsets relative to the wrong base (common off-by-8 confusion between file-relative and item-relative offsets).
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- avif: exif data too short
- avif: invalid exif byte order marker
- avif: invalid exif magic number
- attribute view content is unavailable
- invalid bazaar index generation metadata
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/578e93122563d90c.
Report an issue: GitHub.