lima-vm/lima · error
read block 0: %w
Error message
read block 0: %w
What it means
Thrown by openContainer when f.ReadAt(hdr, 0) cannot read the first 4096 bytes of the disk image — the region that must contain either the NX (container) superblock magic or a GPT protective structures. The underlying read error (short/empty file returning io.EOF, I/O error, device error) is wrapped as "read block 0".
Source
Thrown at pkg/apfs/chown.go:75
// volumeInfo holds resolved volume information.
type volumeInfo struct {
omapTreeAddr uint64 // physical address of volume omap B-tree root
rootTreeOID uint64 // virtual OID of filesystem B-tree root
latestXID uint64 // transaction ID of the volume superblock
}
func openContainer(path string) (*container, error) {
f, err := os.OpenFile(path, os.O_RDWR, 0)
if err != nil {
return nil, fmt.Errorf("open disk: %w", err)
}
c := &container{f: f}
hdr := make([]byte, 4096) // minimum APFS block size
if _, err := f.ReadAt(hdr, 0); err != nil {
f.Close()
return nil, fmt.Errorf("read block 0: %w", err)
}
if le.Uint32(hdr[nxMagicOff:]) == nxMagic {
// Raw APFS container (no partition table).
c.blockSize = le.Uint32(hdr[nxBlockSizeOff:])
} else {
// Look for a GPT partition table and find the APFS partition.
offset, err := findAPFSPartitionGPT(f)
if err != nil {
f.Close()
return nil, fmt.Errorf("finding APFS partition: %w", err)
}
c.baseOffset = offset
if _, err := f.ReadAt(hdr, offset); err != nil {
f.Close()
return nil, fmt.Errorf("read APFS superblock at offset %d: %w", offset, err)
}
if le.Uint32(hdr[nxMagicOff:]) != nxMagic {View on GitHub (pinned to dd909d0973)
Solutions
- Check the image file is non-empty and at least 4096 bytes (`ls -la` / `stat`).
- Re-copy or re-export the disk image if it is truncated.
- Verify you are targeting the correct disk/device path.
- Test raw readability first with a small Go ReadAt or `dd if=image bs=4096 count=1` to isolate I/O problems.
Example fix
// before
apfs.Chown("empty.img", ...) // read block 0: EOF
// after
if fi, err := os.Stat("disk.img"); err == nil && fi.Size() >= 4096 {
apfs.Chown("disk.img", ...)
} Defensive patterns
Strategy: validation
Validate before calling
fi, err := os.Stat(diskPath)
if err != nil || fi.Size() < 4096 {
return fmt.Errorf("image %q too small (%v bytes)", diskPath, fi.Size())
} Try / catch
if err := apfs.Chown(diskPath, role, uid, gid, paths...); err != nil {
if strings.Contains(err.Error(), "read block 0") {
// truncated/unreadable image: re-copy from source
}
return err
} Prevention
- Verify image size after copy/download before processing.
- Checksum images after transfer to detect truncation.
- Avoid reading images directly from flaky removable media; copy to local disk first.
When it happens
Trigger: apfs.Chown called on a zero-length or truncated file (ReadAt at offset 0 on an empty file returns io.EOF), an unreadable block device, or an image on failing storage.
Common situations: Pointing Chown at an empty placeholder file; an interrupted download/copy left a truncated image; a sparse image that failed to materialize; wrong device node for the target disk.
Related errors
- reading container superblock: %w
- reading volume omap: %w
- resolving filesystem root tree OID %d: %w
- resolving path %#q: %w
- chown inode %d (%#q): %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/8251827a9675ee82.
Report an issue: GitHub.