kovidgoyal/kitty · error
Invalid weak_hash in signature header: %d
Error message
Invalid weak_hash in signature header: %d
What it means
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.
Source
Thrown at tools/rsync/api.go:96
switch csum := ChecksumType(bin.Uint16(data[2:])); csum {
case XXH3128Sum:
self.Checksum_type = XXH3128Sum
self.rsync.SetChecksummer(new_xxh3_128)
default:
return consumed, fmt.Errorf("Invalid checksum_type in signature header: %d", csum)
}
switch strong_hash := StrongHashType(bin.Uint16(data[4:])); strong_hash {
case XXH3:
self.Strong_hash_type = strong_hash
self.rsync.SetHasher(new_xxh3_64)
default:
return consumed, fmt.Errorf("Invalid strong_hash in signature header: %d", strong_hash)
}
switch weak_hash := WeakHashType(bin.Uint16(data[6:])); weak_hash {
case Rsync:
self.Weak_hash_type = weak_hash
default:
return consumed, fmt.Errorf("Invalid weak_hash in signature header: %d", weak_hash)
}
block_size := int(bin.Uint32(data[8:]))
consumed = 12
if block_size == 0 {
return consumed, fmt.Errorf("rsync signature header has zero block size")
}
if block_size > MaxBlockSize {
return consumed, fmt.Errorf("rsync signature header has too large block size %d > %d", block_size, MaxBlockSize)
}
self.rsync.BlockSize = block_size
self.signature = make([]BlockHash, 0, 1024)
return
}
func (self *Api) read_signature_blocks(data []byte) (consumed int) {
block_hash_size := self.rsync.HashSize() + 12
for ; len(data) >= block_hash_size; data = data[block_hash_size:] {
bl := BlockHash{}View on GitHub (pinned to 6d5d0c4406)
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
Defensive patterns
Strategy: try-catch
Validate before calling
if len(data) < 8 { return fmt.Errorf("signature data too short") }
wh := binary.BigEndian.Uint16(data[6:8])
if wh != uint16(rsync.Rsync) { return fmt.Errorf("unsupported weak hash %d", wh) } Try / catch
if err := differ.AddSignatureData(buf); err != nil { log.Printf("signature rejected: %v", err); return err } Prevention
- Pin both peers to the same kitty version
- Validate header magic/lengths before feeding data
When it happens
Trigger: 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.
Common situations: Protocol version mismatch between differ and patcher, byte-stream corruption, or accidentally prepending extra bytes before the signature.
Related errors
- rsync signature header has zero block size
- rsync signature header has too large block size %d > %d
- There were %d leftover bytes in the signature data
- There are %d leftover bytes in the delta
- The checksum was not received at the end of the delta data
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/1c008c4264cf3652.
Report an issue: GitHub.