{"record":{"id":"1c008c4264cf3652","repo":"kovidgoyal/kitty","slug":"invalid-weak-hash-in-signature-header-d","errorCode":null,"errorMessage":"Invalid weak_hash in signature header: %d","messagePattern":"Invalid weak_hash in signature header: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/rsync/api.go","lineNumber":96,"sourceCode":"\tswitch csum := ChecksumType(bin.Uint16(data[2:])); csum {\n\tcase XXH3128Sum:\n\t\tself.Checksum_type = XXH3128Sum\n\t\tself.rsync.SetChecksummer(new_xxh3_128)\n\tdefault:\n\t\treturn consumed, fmt.Errorf(\"Invalid checksum_type in signature header: %d\", csum)\n\t}\n\tswitch strong_hash := StrongHashType(bin.Uint16(data[4:])); strong_hash {\n\tcase XXH3:\n\t\tself.Strong_hash_type = strong_hash\n\t\tself.rsync.SetHasher(new_xxh3_64)\n\tdefault:\n\t\treturn consumed, fmt.Errorf(\"Invalid strong_hash in signature header: %d\", strong_hash)\n\t}\n\tswitch weak_hash := WeakHashType(bin.Uint16(data[6:])); weak_hash {\n\tcase Rsync:\n\t\tself.Weak_hash_type = weak_hash\n\tdefault:\n\t\treturn consumed, fmt.Errorf(\"Invalid weak_hash in signature header: %d\", weak_hash)\n\t}\n\tblock_size := int(bin.Uint32(data[8:]))\n\tconsumed = 12\n\tif block_size == 0 {\n\t\treturn consumed, fmt.Errorf(\"rsync signature header has zero block size\")\n\t}\n\tif block_size > MaxBlockSize {\n\t\treturn consumed, fmt.Errorf(\"rsync signature header has too large block size %d > %d\", block_size, MaxBlockSize)\n\t}\n\tself.rsync.BlockSize = block_size\n\tself.signature = make([]BlockHash, 0, 1024)\n\treturn\n}\n\nfunc (self *Api) read_signature_blocks(data []byte) (consumed int) {\n\tblock_hash_size := self.rsync.HashSize() + 12\n\tfor ; len(data) >= block_hash_size; data = data[block_hash_size:] {\n\t\tbl := BlockHash{}","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/tools/rsync/api.go#L78-L114","documentation":"The rsync signature header stores a weak-hash algorithm id at bytes 6-7; read_signature_header accepts only Rsync. Any other id means the signature was produced with an incompatible or corrupt hash configuration.","triggerScenarios":"Feeding AddSignatureData bytes whose header weak_hash field is not the Rsync id — typically a truncated/garbled stream or a signature generated by a different implementation/version.","commonSituations":"Protocol version mismatch between differ and patcher, byte-stream corruption, or accidentally prepending extra bytes before the signature.","solutions":["Ensure both ends use the same kitty/rsync tool version and hash settings","Verify the byte stream starts exactly at the signature header","Regenerate the signature on the source side and retry the transfer"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if len(data) < 8 { return fmt.Errorf(\"signature data too short\") }\nwh := binary.BigEndian.Uint16(data[6:8])\nif wh != uint16(rsync.Rsync) { return fmt.Errorf(\"unsupported weak hash %d\", wh) }","typeGuard":null,"tryCatchPattern":"if err := differ.AddSignatureData(buf); err != nil { log.Printf(\"signature rejected: %v\", err); return err }","preventionTips":["Pin both peers to the same kitty version","Validate header magic/lengths before feeding data"],"tags":["rsync","protocol","header","corruption"],"backgroundTag":"protocol-header-invalid","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}