{"record":{"id":"e92817f09e6a351c","repo":"lima-vm/lima","slug":"inode-d-value-exceeds-block-boundary","errorCode":null,"errorMessage":"inode %d value exceeds block boundary","messagePattern":"inode (.+?) value exceeds block boundary","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apfs/chown.go","lineNumber":679,"sourceCode":"\t\tif isRoot {\n\t\t\tvalueAreaEnd -= btreeInfoSize\n\t\t}\n\n\t\tif isLeaf {\n\t\t\tfor i := range nkeys {\n\t\t\t\tkOff, vOff := c.readTocEntry(blk, tocStart, i, isFixedKV)\n\t\t\t\tkeyStart := keyAreaStart + kOff\n\t\t\t\tkeyHeader := le.Uint64(blk[keyStart:])\n\n\t\t\t\tif keyHeader != targetKeyHeader {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\t// Found the inode. Validate before writing.\n\t\t\t\tvalStart := valueAreaEnd - vOff\n\n\t\t\t\tif valStart+inodeGroupOff+4 > c.blockSize {\n\t\t\t\t\treturn fmt.Errorf(\"inode %d value exceeds block boundary\", inodeNum)\n\t\t\t\t}\n\n\t\t\t\tif privateID := le.Uint64(blk[valStart+inodePrivateIDOff:]); privateID != inodeNum {\n\t\t\t\t\treturn fmt.Errorf(\"inode %d has mismatched private_id %d\", inodeNum, privateID)\n\t\t\t\t}\n\n\t\t\t\tcurrentUID := le.Uint32(blk[valStart+inodeOwnerOff:])\n\t\t\t\tcurrentGID := le.Uint32(blk[valStart+inodeGroupOff:])\n\t\t\t\tif currentUID != noownersPlaceholderID || currentGID != noownersPlaceholderID {\n\t\t\t\t\treturn fmt.Errorf(\"inode %d has ownership %d:%d, expected %d:%d from noowners mount\",\n\t\t\t\t\t\tinodeNum, currentUID, currentGID, noownersPlaceholderID, noownersPlaceholderID)\n\t\t\t\t}\n\n\t\t\t\tle.PutUint32(blk[valStart+inodeOwnerOff:], uid)\n\t\t\t\tle.PutUint32(blk[valStart+inodeGroupOff:], gid)\n\t\t\t\tupdateChecksum(blk)\n\t\t\t\treturn c.writeBlock(blkAddr, blk)\n\t\t\t}","sourceCodeStart":661,"sourceCodeEnd":697,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/apfs/chown.go#L661-L697","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm the reader's blockSize matches the image\napsb, _ := readVolumeSuperblock(imagePath)\nif c.blockSize != apsb.BlockSize {\n    return fmt.Errorf(\"blockSize mismatch: reader %d, image %d\", c.blockSize, apsb.BlockSize)\n}","typeGuard":"func isBlockBoundaryError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"exceeds block boundary\")\n}","tryCatchPattern":"if err := c.chownInode(root, omap, maxXID, ino, uid, gid); isBlockBoundaryError(err) {\n    return fmt.Errorf(\"value layout inconsistent; check blockSize/format: %w\", err)\n}","preventionTips":["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"],"tags":["apfs","inode","bounds-check","block-size","chown"],"backgroundTag":"block-boundary-exceeded","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}