kovidgoyal/kitty · error

Failed to create a SHM file for transmission: %w

Error message

Failed to create a SHM file for transmission: %w

What it means

The first shm.CreateTemp (for file-backed frame data) failed. icat creates a POSIX shared-memory object (/dev/shm on Linux) sized to the image data; creation can fail if shm is unavailable, full, or size-limited.

Source

Thrown at kittens/icat/transmit.go:101

}

func transmit_shm(imgd *image_data, frame_num int, frame *image_frame) (err error) {
	var mmap shm.MMap
	var data_size int64
	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()))

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Increase /dev/shm size (docker --shm-size=..., or tmpfs mount) or scale/resize the image smaller
  2. Force a different transmission path (e.g. --transfer-mode file/stream) so shm isn't used
  3. Check that /dev/shm is mounted and writable

Example fix

# before
docker run ... kitten icat huge.gif
# after
docker run --shm-size=1g ... kitten icat huge.gif
Defensive patterns

Strategy: validation

Validate before calling

var s syscall.Statfs_t
syscall.Statfs("/dev/shm", &s)
avail := s.Bavail * uint64(s.Bsize)
if avail < uint64(imgSize) { /* resize image or use file/stream transfer */ }

Try / catch

if err != nil && strings.Contains(err.Error(), "SHM file") { /* fallback to --transfer-mode file */ }

Prevention

When it happens

Trigger: Large image where uint64(data_size) exceeds /dev/shm limits; /dev/shm not mounted; RLIMIT/shm permissions deny creation.

Common situations: Containers with tiny or missing /dev/shm (Docker default 64MB); huge animated GIF frames; hardened systems restricting shm_open.

Related errors


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