kovidgoyal/kitty · error

rsync signature header has too large block size %d > %d

Error message

rsync signature header has too large block size %d > %d

What it means

The signature header's block size exceeds MaxBlockSize, so the header is rejected as implausible/corrupt rather than allowing huge memory allocations.

Source

Thrown at tools/rsync/api.go:104

	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{}
		bl.Unserialize(data[:block_hash_size])
		self.signature = append(self.signature, bl)
		consumed += block_hash_size
	}
	return
}

func (self *Differ) FinishSignatureData() (err error) {

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Ensure both sides run the same kitty/rsync implementation version
  2. Verify the stream is intact (re-transfer or recompute the signature)
  3. Check that no bytes were skipped or inserted before the header
Defensive patterns

Strategy: try-catch

Validate before calling

if bs := binary.BigEndian.Uint32(data[8:12]); bs == 0 || int(bs) > rsync.MaxBlockSize { return fmt.Errorf("implausible block size %d", bs) }

Try / catch

if err := differ.AddSignatureData(chunk); err != nil { log.Printf("invalid signature header: %v", err); re-request signature }

Prevention

When it happens

Trigger: A header whose uint32 block-size field is larger than MaxBlockSize — from corruption, or a peer using a different/incompatible block size configuration.

Common situations: Version drift where one side allows larger blocks, byte-order mistakes, or feeding arbitrary binary data as signature input.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/b4a951bf688a5653. Report an issue: GitHub.