lima-vm/lima · error
inode %d value exceeds block boundary
Error message
inode %d value exceeds block boundary
What it means
chownInode found the inode's key in a leaf node, but computing the write location showed the inode value's uid/gid fields (valStart + inodeGroupOff + 4) would extend past the end of the block. This is a bounds check that prevents out-of-range writes; it means the stored value offset (vOff) is inconsistent with the block size.
Source
Thrown at pkg/apfs/chown.go:679
if isRoot {
valueAreaEnd -= btreeInfoSize
}
if isLeaf {
for i := range nkeys {
kOff, vOff := c.readTocEntry(blk, tocStart, i, isFixedKV)
keyStart := keyAreaStart + kOff
keyHeader := le.Uint64(blk[keyStart:])
if keyHeader != targetKeyHeader {
continue
}
// Found the inode. Validate before writing.
valStart := valueAreaEnd - vOff
if valStart+inodeGroupOff+4 > c.blockSize {
return fmt.Errorf("inode %d value exceeds block boundary", inodeNum)
}
if privateID := le.Uint64(blk[valStart+inodePrivateIDOff:]); privateID != inodeNum {
return fmt.Errorf("inode %d has mismatched private_id %d", inodeNum, privateID)
}
currentUID := le.Uint32(blk[valStart+inodeOwnerOff:])
currentGID := le.Uint32(blk[valStart+inodeGroupOff:])
if currentUID != noownersPlaceholderID || currentGID != noownersPlaceholderID {
return fmt.Errorf("inode %d has ownership %d:%d, expected %d:%d from noowners mount",
inodeNum, currentUID, currentGID, noownersPlaceholderID, noownersPlaceholderID)
}
le.PutUint32(blk[valStart+inodeOwnerOff:], uid)
le.PutUint32(blk[valStart+inodeGroupOff:], gid)
updateChecksum(blk)
return c.writeBlock(blkAddr, blk)
}View on GitHub (pinned to dd909d0973)
Solutions
- Verify c.blockSize matches the apsb block_size field of the image
- Run fsck_apfs; a corrupt toc entry needs repair before any write
- Skip/abort the operation for this inode rather than writing out of bounds
- Check that the leaf's root flag handling (btreeInfoSize subtraction) matches the node being parsed
Defensive patterns
Strategy: validation
Validate before calling
// Confirm the reader's blockSize matches the image
apsb, _ := readVolumeSuperblock(imagePath)
if c.blockSize != apsb.BlockSize {
return fmt.Errorf("blockSize mismatch: reader %d, image %d", c.blockSize, apsb.BlockSize)
} Type guard
func isBlockBoundaryError(err error) bool {
return err != nil && strings.Contains(err.Error(), "exceeds block boundary")
} Try / catch
if err := c.chownInode(root, omap, maxXID, ino, uid, gid); isBlockBoundaryError(err) {
return fmt.Errorf("value layout inconsistent; check blockSize/format: %w", err)
} Prevention
- Initialize the container from the apsb block_size, never a constant
- Run fsck_apfs when toc/value offsets look inconsistent
- Skip and log the offending inode instead of forcing the write
When it happens
Trigger: A leaf node whose toc entry yields a value offset placing the inode value beyond blockSize — corrupt or foreign toc data, wrong blockSize assumption (e.g. image formatted with non-default block size the reader doesn't honor), or a root node's btreeInfo tail misaccounted.
Common situations: Reading images formatted with block sizes other than the assumed one; corrupted toc entries after fs damage; parsing a node type whose value layout differs.
Related errors
- inode %d has mismatched private_id %d
- inode %d has ownership %d:%d, expected %d:%d from noowners m
- inode %d not found in filesystem B-tree
- resolving filesystem root tree OID %d: %w
- resolving path %#q: %w
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/e92817f09e6a351c.
Report an issue: GitHub.