gohugoio/hugo · error

exif failed: %v

Error message

exif failed: %v

What it means

Decoder.Decode in Hugo's image metadata package extracts EXIF data (dates, GPS, tags) from an image via the github.com/gohugoio/imagemeta library. The whole decode runs under a deferred recover(), so this error means the EXIF parser panicked — usually on malformed, truncated, or maliciously crafted EXIF blocks — and Hugo converted the panic into an error instead of crashing the build.

Source

Thrown at resources/images/meta/meta.go:219

	}

	return d, nil
}

var (
	isTimeTag = func(s string) bool {
		return strings.Contains(s, "Time")
	}
	isGPSTag = func(s string) bool {
		return strings.HasPrefix(s, "GPS")
	}
)

// Filename is only used for logging.
func (d *Decoder) Decode(filename string, format imagemeta.ImageFormat, r io.Reader) (ex *ExifInfo, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("exif failed: %v", r)
		}
	}()

	var tagInfos imagemeta.Tags
	handleTag := func(ti imagemeta.TagInfo) error {
		tagInfos.Add(ti)
		return nil
	}

	shouldHandleTag := func(ti imagemeta.TagInfo) bool {
		if ti.Source == imagemeta.EXIF {
			if !d.noDate {
				// We need the time tags to calculate the date.
				if isTimeTag(ti.Tag) {
					return true
				}
			}
			if !d.noLatLong {

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Identify the offending image from the build log and re-export or strip its EXIF (e.g. `exiftool -all= image.jpg`), then rebuild.
  2. Verify the file isn't truncated/corrupt (open it in an image viewer, check its size against the original).
  3. Upgrade Hugo — imagemeta panic fixes land regularly; if it still panics on a valid image, report it upstream with the file.

Example fix

# before: template fails with "exif failed: ..." on a corrupt photo
{{ with .Resources.GetMatch "photo.jpg" }}{{ .Exif.Date }}{{ end }}
# after: strip the broken EXIF block from the asset
exiftool -all= assets/photo.jpg
Defensive patterns

Strategy: try-catch

Try / catch

meta, err := img.Exif()
if err != nil {
    log.Printf("skipping exif for %s: %v", img.Name(), err)
    // proceed without exif rather than failing the build
}

Prevention

When it happens

Trigger: Calling .Exif on an image resource in a template (which drives Decoder.Decode) against a file whose EXIF segment causes a panic in imagemeta — corrupt IFD offsets, truncated files, or unusual maker notes. The recovered panic value is embedded verbatim in the error.

Common situations: Photos exported or stripped by buggy tools, images truncated during download/git-lfs mishaps, files renamed to the wrong extension, or edge-case EXIF from unusual cameras/phones. Behavior can change across Hugo versions as the bundled imagemeta version changes.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/e6299e0dfa80378a.json. Report an issue: GitHub ↗.