AlistGo/alist · warning
failed to open image: %w
Error message
failed to open image: %w
What it means
generateThumbnailWithImagingOptimized calls os.Open on the image path and Go's standard library failed. The wrapped *PathError explains the cause: ENOENT (file removed since listing), EACCES (permission denied for the process user), or EMFILE (too many open file descriptors under heavy thumbnail traffic).
Source
Thrown at drivers/local/util.go:121
WithOutput(outBuffer, os.Stderr). // Capture stdout to outBuffer, stderr to os.Stderr
// ErrorToStdOut(). // Alternative: send ffmpeg's stderr to Go's stdout
Run()
if err != nil {
return nil, fmt.Errorf("ffmpeg-go failed to resize image %s to buffer: %w", inputFile, err)
}
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.PNGView on GitHub (pinned to 843d9dc814)
Solutions
- Check the wrapped PathError for the syscall reason (no such file / permission denied / too many open files)
- Confirm the process user can read the file: sudo -u <alistuser> head -c1 <path>
- If EMFILE, raise the file descriptor limit (ulimit -n / LimitNOFILE) or reduce concurrent thumbnail workers
- If files are transiently missing, treat the error as non-fatal and skip caching the thumbnail
Defensive patterns
Strategy: validation
Validate before calling
func canRead(path string) bool {
f, err := os.Open(path)
if err != nil {
return false
}
f.Close()
return true
} Try / catch
Check errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrPermission): for ErrNotExist skip silently (file raced away); for ErrPermission log once per directory; for EMFILE throttle concurrency.
Prevention
- Run the process with read access to all media roots
- Raise LimitNOFILE / ulimit -n when serving large libraries
- Handle deletion races by treating ENOENT as 'no thumbnail', not an error
When it happens
Trigger: Thumbnail request racing with file deletion, read permissions not granted to the alist/OpenList process user, NFS/SMB mount not yet mounted or stale, or fd exhaustion when many thumbnails are generated concurrently.
Common situations: Media directory on a network mount that dropped; files renamed/deleted by another process between list and thumb requests; systemd/docker service user lacking read access to the media folder.
Related errors
- invalid input file path: %w
- ffmpeg-go failed to resize image %s to buffer: %w
- ffmpeg-go produced empty buffer for %s
- failed to decode image: %w
- failed to encode thumbnail: %w
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/d3efbe53b172f832.
Report an issue: GitHub.