kovidgoyal/kitty · error

No header was found in the signature data

Error message

No header was found in the signature data

What it means

FinishSignatureData succeeded in consuming all bytes but no valid header was ever parsed, so the rsync hasher (block size + hash config) was never initialized.

Source

Thrown at tools/rsync/api.go:128

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) {
	if len(self.unconsumed_signature_data) > 0 {
		return fmt.Errorf("There were %d leftover bytes in the signature data", len(self.unconsumed_signature_data))
	}
	self.unconsumed_signature_data = nil
	if !self.rsync.HasHasher() {
		return fmt.Errorf("No header was found in the signature data")
	}
	return
}

func (self *Patcher) update_delta(data []byte) (consumed int, err error) {
	op := Operation{}
	for len(data) > 0 {
		n, uerr := op.Unserialize(data)
		if uerr == nil {
			consumed += n
			data = data[n:]
			if err = self.rsync.ApplyDelta(self.delta_output, self.delta_input, op); err != nil {
				return
			}
			if op.Type == OpData {
				self.total_data_in_delta += len(op.Data)
			}
		} else {

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Ensure AddSignatureData receives the header bytes first, then block data, then call FinishSignatureData
  2. Check the sender actually transmitted a signature
  3. If the stream is legitimately empty, skip delta creation rather than finishing an empty differ
Defensive patterns

Strategy: validation

Validate before calling

if totalSignatureBytesReceived == 0 { skip delta creation; empty signature }

Type guard

func hasSignatureHeader(received int) bool { return received >= 12 }

Try / catch

if err := differ.FinishSignatureData(); err != nil { if strings.Contains(err.Error(), "No header") { handle empty source } else { return err } }

Prevention

When it happens

Trigger: Calling FinishSignatureData before AddSignatureData has processed the 12-byte signature header — including calling it immediately with no data at all.

Common situations: Empty signature stream (peer sent nothing), or calling the API out of order (finish before add), or the header arriving only after finish was already invoked.

Related errors


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