kovidgoyal/kitty · error

Failed to read data from image output data file

Error message

Failed to read data from image output data file: %w

What it means

io.ReadFull failed while copying the frame file's bytes into the shared-memory segment — fewer bytes were available than the earlier size determination promised, or a read error occurred.

Solutions

  1. Retry the icat run
  2. Point TMPDIR at stable local storage
  3. Avoid running concurrent icat instances over the same temp files
Defensive patterns

Strategy: retry

Validate before calling

fi, _ := os.Stat(f)
// verify size unchanged between sizing and reading before transmit

Try / catch

if err != nil && strings.Contains(err.Error(), "Failed to read data") { /* regenerate frame and retry once */ }

Prevention

When it happens

Trigger: File truncated between Seek (size) and ReadFull, or an I/O error mid-read from disk/NFS.

Common situations: Concurrent truncation of temp files; flaky network filesystems hosting TMPDIR; race with cleanup processes.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/1f9b7689bd424236. Report an issue: GitHub.

Appendix: source

Thrown at kittens/icat/transmit.go:106

	if frame.in_memory_bytes == nil {
		f, err := os.Open(frame.filename)
		if err != nil {
			return fmt.Errorf("Failed to open image data output file: %s with error: %w", frame.filename, err)
		}
		defer f.Close()
		if data_size, err = f.Seek(0, io.SeekEnd); err != nil {
			return fmt.Errorf("Failed to seek in image data output file: %s with error: %w", frame.filename, err)
		}
		if _, err = f.Seek(0, io.SeekStart); err != nil {
			return fmt.Errorf("Failed to seek in image data output file: %s with error: %w", frame.filename, err)
		}
		if mmap, err = shm.CreateTemp("icat-*", uint64(data_size)); err != nil {
			return fmt.Errorf("Failed to create a SHM file for transmission: %w", err)
		}
		if _, err = io.ReadFull(f, mmap.Slice()); err != nil {
			mmap.Close()
			mmap.Unlink()
			return fmt.Errorf("Failed to read data from image output data file: %w", err)
		}
	} else {
		data_size = int64(len(frame.in_memory_bytes))
		if mmap, err = shm.CreateTemp("icat-*", uint64(data_size)); err != nil {
			return fmt.Errorf("Failed to create a SHM file for transmission: %w", err)
		}
		copy(mmap.Slice(), frame.in_memory_bytes)
	}
	defer mmap.Close() // terminal is responsible for unlink
	gc := gc_for_image(imgd, frame_num, frame)
	gc.SetTransmission(graphics.GRT_transmission_sharedmem)
	gc.SetDataSize(uint64(data_size))
	err = gc.WriteWithPayloadTo(os.Stdout, utils.UnsafeStringToBytes(mmap.Name()))
	return
}

func transmit_file(imgd *image_data, frame_num int, frame *image_frame) (err error) {
	is_temp := false

View on GitHub (pinned to 6d5d0c4406)