{"record":{"id":"84c660320b111257","repo":"kovidgoyal/kitty","slug":"there-were-d-leftover-bytes-in-the-signature-data","errorCode":null,"errorMessage":"There were %d leftover bytes in the signature data","messagePattern":"There were (.+?) leftover bytes in the signature data","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tools/rsync/api.go","lineNumber":124,"sourceCode":"\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{}\n\t\tbl.Unserialize(data[:block_hash_size])\n\t\tself.signature = append(self.signature, bl)\n\t\tconsumed += block_hash_size\n\t}\n\treturn\n}\n\nfunc (self *Differ) FinishSignatureData() (err error) {\n\tif len(self.unconsumed_signature_data) > 0 {\n\t\treturn fmt.Errorf(\"There were %d leftover bytes in the signature data\", len(self.unconsumed_signature_data))\n\t}\n\tself.unconsumed_signature_data = nil\n\tif !self.rsync.HasHasher() {\n\t\treturn fmt.Errorf(\"No header was found in the signature data\")\n\t}\n\treturn\n}\n\nfunc (self *Patcher) update_delta(data []byte) (consumed int, err error) {\n\top := Operation{}\n\tfor len(data) > 0 {\n\t\tn, uerr := op.Unserialize(data)\n\t\tif uerr == nil {\n\t\t\tconsumed += n\n\t\t\tdata = data[n:]\n\t\t\tif err = self.rsync.ApplyDelta(self.delta_output, self.delta_input, op); err != nil {\n\t\t\t\treturn\n\t\t\t}","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/tools/rsync/api.go#L106-L142","documentation":"After consuming all signature blocks, FinishSignatureData found unconsumed bytes left over — the stream length is not consistent with the header's declared block count, indicating truncation, corruption, or extra data.","triggerScenarios":"Calling FinishSignatureData when AddSignatureData was fed a byte count not matching whole signature blocks plus header; e.g. stopping mid-block or appending trailing bytes.","commonSituations":"Partial reads from a network/socket, misframed transfers, or calling FinishSignatureData before all data arrived.","solutions":["Make sure every chunk of signature data was passed to AddSignatureData before finishing","Verify the transfer framing so no bytes are lost or duplicated","Regenerate and resend the full signature"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := differ.FinishSignatureData(); err != nil { log.Printf(\"signature incomplete: %v\", err); re-fetch signature and retry once }","preventionTips":["Feed all received chunks to AddSignatureData before finishing","Use length-prefixed framing so truncation is detectable"],"tags":["rsync","protocol","stream","corruption"],"backgroundTag":"protocol-stream-corrupted","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}