AlistGo/alist · warning

failed to decode image: %w

Error message

failed to decode image: %w

What it means

imaging.Decode (github.com/disintegration/imaging with AutoOrientation) failed to decode the opened file. It uses Go's image.RegisterFormat-registered decoders, so it natively supports JPEG/PNG/GIF/BMP/TIFF only. The wrapped error is image.ErrFormat ('image: unknown format') for anything else, or a decode error for truncated/corrupt data.

Source

Thrown at drivers/local/util.go:127

	}
	if outBuffer == nil || outBuffer.Len() == 0 {
		return nil, fmt.Errorf("ffmpeg-go produced empty buffer for %s", inputFile)
	}

	return outBuffer, nil
}

func generateThumbnailWithImagingOptimized(imagePath string, targetWidth int, quality int) (*bytes.Buffer, error) {

	file, err := os.Open(imagePath)
	if err != nil {
		return nil, fmt.Errorf("failed to open image: %w", err)
	}
	defer file.Close()

	img, err := imaging.Decode(file, imaging.AutoOrientation(true))
	if err != nil {
		return nil, fmt.Errorf("failed to decode image: %w", err)
	}

	thumbImg := imaging.Resize(img, targetWidth, 0, imaging.Lanczos)
	img = nil

	var buf bytes.Buffer
	// imaging.Encode
	// imaging.PNG, imaging.JPEG, imaging.GIF, imaging.BMP, imaging.TIFF
	outputFormat := imaging.JPEG
	encodeOptions := []imaging.EncodeOption{imaging.JPEGQuality(quality)}

	// outputFormat := imaging.PNG
	// encodeOptions := []imaging.EncodeOption{}

	err = imaging.Encode(&buf, thumbImg, outputFormat, encodeOptions...)
	if err != nil {
		return nil, fmt.Errorf("failed to encode thumbnail: %w", err)
	}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Identify the actual format: 'file <path>' — if WebP/HEIC/AVIF, enable the driver's useFFmpeg option so ffmpeg handles decoding
  2. If you must stay pure-Go, register a WebP decoder (e.g. golang.org/x/image/webp) via image.RegisterFormat before imaging.Decode
  3. For corrupt/truncated files, re-obtain the source file

Example fix

// before: default decoders only (JPEG/PNG/GIF/BMP/TIFF)
img, err := imaging.Decode(file, imaging.AutoOrientation(true))

// after: register WebP support once at init, then decode
import (
    "image"
    _ "golang.org/x/image/webp"
)
func init() {
    image.RegisterFormat("webp", "RIFF????WEBPVP8", webp.Decode, webp.DecodeConfig)
}
Defensive patterns

Strategy: fallback

Validate before calling

// sniff the format first to decide the decoder route
func decodeWithFallback(path string) (image.Image, error) {
    f, _ := os.Open(path)
    defer f.Close()
    _, format, err := image.DecodeConfig(f)
    if err != nil {
        return nil, err // unknown format -> use ffmpeg route
    }
    if _, err := f.Seek(0, io.SeekStart); err != nil { return nil, err }
    return imaging.Decode(f, imaging.AutoOrientation(true))
}

Try / catch

if _, err := imaging.Decode(file, imaging.AutoOrientation(true)); err != nil { if errors.Is(err, image.ErrFormat) { switch to resizeImageToBufferWithFFmpegGo } else { return err } }

Prevention

When it happens

Trigger: Decoding a WebP, HEIC, AVIF, or SVG file — none are registered by default; decoding a truncated JPEG (download interrupted); decoding a file whose magic bytes are recognized but whose data stream is corrupt.

Common situations: The exact scenario that pushes users to enable useFFmpeg: modern phone photos in HEIC/WebP are not decodable by the pure-Go path. Also partially-written files and zero-byte images.

Understand the failure class

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/04d6bfe37b6e1ebd. Report an issue: GitHub.