{"record":{"id":"6e362f9de1af2695","repo":"HelloZeroNet/ZeroNet","slug":"invalid-hash","errorCode":null,"errorMessage":"Invalid hash","messagePattern":"Invalid hash","errorType":"validation","errorClass":"VerifyError","httpStatus":null,"severity":"error","filePath":"plugins/Bigfile/BigfilePlugin.py","lineNumber":399,"sourceCode":"        return back\n\n    def getPiecemap(self, inner_path):\n        file_info = self.site.content_manager.getFileInfo(inner_path)\n        piecemap_inner_path = helper.getDirname(file_info[\"content_inner_path\"]) + file_info[\"piecemap\"]\n        self.site.needFile(piecemap_inner_path, priority=20)\n        piecemap = Msgpack.unpack(self.site.storage.open(piecemap_inner_path, \"rb\").read())[helper.getFilename(inner_path)]\n        piecemap[\"piece_size\"] = file_info[\"piece_size\"]\n        return piecemap\n\n    def verifyPiece(self, inner_path, pos, piece):\n        try:\n            piecemap = self.getPiecemap(inner_path)\n        except Exception as err:\n            raise VerifyError(\"Unable to download piecemap: %s\" % Debug.formatException(err))\n\n        piece_i = int(pos / piecemap[\"piece_size\"])\n        if CryptHash.sha512sum(piece, format=\"digest\") != piecemap[\"sha512_pieces\"][piece_i]:\n            raise VerifyError(\"Invalid hash\")\n        return True\n\n    def verifyFile(self, inner_path, file, ignore_same=True):\n        if \"|\" not in inner_path:\n            return super(ContentManagerPlugin, self).verifyFile(inner_path, file, ignore_same)\n\n        inner_path, file_range = inner_path.split(\"|\")\n        pos_from, pos_to = map(int, file_range.split(\"-\"))\n\n        return self.verifyPiece(inner_path, pos_from, file)\n\n    def optionalDownloaded(self, inner_path, hash_id, size=None, own=False):\n        if \"|\" in inner_path:\n            inner_path, file_range = inner_path.split(\"|\")\n            pos_from, pos_to = map(int, file_range.split(\"-\"))\n            file_info = self.getFileInfo(inner_path)\n\n            # Mark piece downloaded","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/HelloZeroNet/ZeroNet/blob/454c0b2e7e000fda7000cba49027541fbf327b96/plugins/Bigfile/BigfilePlugin.py#L381-L417","documentation":"verifyPiece() hashes the downloaded piece with sha512 and compares it against the expected digest stored in the piecemap. A mismatch means the piece data is corrupt, tampered with, or does not match the published piecemap, so verification fails with VerifyError('Invalid hash').","triggerScenarios":"A downloaded piece from a peer differs from the published sha512 digest: corrupted transfer, malicious peer serving wrong data, position math mismatch (pos not aligned to piece boundaries), or stale piecemap after the big file was modified but not repacked.","commonSituations":"Bit-flip corruption on disk/network; peer serving modified content; file edited/re-encoded after content.json/piecemap was signed; mismatched piece_size between the file and piecemap.","solutions":["Delete the affected file from the site data directory and re-download it from other peers","Verify with multiple peers — if only one serves bad data, blacklist/mute that peer and refetch","If you are the site owner: repack the big file and re-sign content.json so piecemap hashes match the current file","Check that pos passed to verifyPiece is piece-aligned (int(pos / piece_size) must be the intended piece index)"],"exampleFix":"// before\nverifyPiece(inner_path, pos, piece)  # pos from a stale/offset cursor\n// after\npiece_size = piecemap['piece_size']\nassert pos % piece_size == 0, 'piece position not aligned'\nverifyPiece(inner_path, pos, piece)","handlingStrategy":"try-catch","validationCode":"# detect file-modified-after-signing\nlocal_hash = CryptHash.sha512sum(open(file_path,'rb').read(), format='digest')\nexpected = content_json['files'][inner_path]['sha512']\nif local_hash != expected: re_pack_and_sign_site()","typeGuard":null,"tryCatchPattern":"try:\n    site.verifyFile(inner_path, f)\nexcept VerifyError as err:\n    if str(err) == 'Invalid hash':\n        delete_corrupted_piece_and_redownload(inner_path, pos)\n    else:\n        raise","preventionTips":["Never edit a big file after publishing without repacking and re-signing content.json","Re-download pieces that fail verification from different peers","Keep disk and network healthy (check SMART, use TLS/verified transports)","Sanity-check piece positions are multiples of piece_size before hashing"],"tags":["verification","hash-mismatch","bigfile","integrity"],"backgroundTag":"hash-verification-failed","analyzedSha":"454c0b2e7e000fda7000cba49027541fbf327b96","analyzedAt":"2026-09-02T19:46:57.278Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}