{"record":{"id":"e6299e0dfa80378a","repo":"gohugoio/hugo","slug":"exif-failed-v","errorCode":null,"errorMessage":"exif failed: %v","messagePattern":"exif failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"resources/images/meta/meta.go","lineNumber":219,"sourceCode":"\t}\n\n\treturn d, nil\n}\n\nvar (\n\tisTimeTag = func(s string) bool {\n\t\treturn strings.Contains(s, \"Time\")\n\t}\n\tisGPSTag = func(s string) bool {\n\t\treturn strings.HasPrefix(s, \"GPS\")\n\t}\n)\n\n// Filename is only used for logging.\nfunc (d *Decoder) Decode(filename string, format imagemeta.ImageFormat, r io.Reader) (ex *ExifInfo, err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"exif failed: %v\", r)\n\t\t}\n\t}()\n\n\tvar tagInfos imagemeta.Tags\n\thandleTag := func(ti imagemeta.TagInfo) error {\n\t\ttagInfos.Add(ti)\n\t\treturn nil\n\t}\n\n\tshouldHandleTag := func(ti imagemeta.TagInfo) bool {\n\t\tif ti.Source == imagemeta.EXIF {\n\t\t\tif !d.noDate {\n\t\t\t\t// We need the time tags to calculate the date.\n\t\t\t\tif isTimeTag(ti.Tag) {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !d.noLatLong {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/resources/images/meta/meta.go#L201-L237","documentation":"Returned (not panicked) by Decoder.Decode when the underlying imagemeta.Decode panics during EXIF parsing. The deferred recover() at meta.go:219 catches the panic and converts it to an error with %v formatting (note: %v, not %w — so the original panic value is stringified, not wrappable). This means Hugo degrades gracefully on malformed EXIF rather than crashing the build.","triggerScenarios":"An image file with malformed, truncated, or non-standard EXIF data causes the EXIF parser to panic. The recover block catches it and returns this error to the caller. Common with images edited by tools that write non-compliant EXIF blocks.","commonSituations":"Photos edited by older mobile apps that write non-standard EXIF; images with manually edited or stripped metadata that left corrupt IFD entries; HEIC files converted to JPEG with a buggy converter; images from scanner software with malformed tags.","solutions":["Strip and re-write the EXIF metadata using exiftool: 'exiftool -all= -tagsfromfile @ -CreateDate path/to/image.jpg'.","Re-export the image from the original using a reliable tool (ImageMagick, libvips) to produce clean metadata.","If the image is not critical, exclude EXIF processing by setting imaging.exif.includeFields or excludeFields to limit parsing scope.","If you cannot fix the source image, consider setting disableDate and disableLatLong to reduce the EXIF tags Hugo needs to parse."],"exampleFix":"# before: image has corrupt EXIF causing 'exif failed: <panic message>'\n\n# Fix the image's EXIF from the shell:\n# exiftool -overwrite_original -all= path/to/image.jpg\n# (strips all metadata; re-add what you need)\n\n# Or in hugo.toml, narrow EXIF parsing to avoid the problematic tags:\n[imaging.exif]\nexcludeFields = \"GPS|Exif|Exposure[M|P|B]|Contrast|Resolution|Sharp|JPEG|Metering|Sensing|Saturation|ColorSpace|Flash|WhiteBalance\"","handlingStrategy":"try-catch","validationCode":"// Pre-validate EXIF integrity before Hugo parses it\n// From the shell:\n// exiftool -verify path/to/image.jpg\n// (exit code non-zero indicates corrupt EXIF)\n\n// Or strip all EXIF to avoid the issue entirely:\n// exiftool -overwrite_original -all= path/to/image.jpg","typeGuard":null,"tryCatchPattern":"// The Decode method already recovers internally and returns an error.\n// Handle it gracefully at the call site:\nexifInfo, err := decoder.Decode(filename, format, reader)\nif err != nil {\n    // err will contain 'exif failed: <panic message>'\n    log.Printf(\"warning: skipping EXIF for %s: %v\", filename, err)\n    exifInfo = &ExifInfo{} // proceed without EXIF data\n}","preventionTips":["Run 'exiftool -verify' on images from untrusted sources (user uploads, third-party APIs) before committing.","Strip non-essential EXIF tags with exiftool to reduce the surface for parser panics.","Use imaging.exif.excludeFields to limit which tags Hugo parses, reducing exposure to malformed data.","Note this error uses %v not %w, so errors.Is/errors.Unwrap will not work — match on the message prefix."],"tags":["hugo","imaging","exif","metadata","corrupt-file"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}