kopia/kopia · error

invalid data - too short

Error message

invalid data - too short

What it means

hmac.VerifyAndStrip expects input whose trailing sha256.Size (32) bytes are an HMAC-SHA256 signature appended by the writer. If the input is shorter than 32 bytes there cannot be a signature, so it fails immediately with 'invalid data - too short'.

Solutions

  1. Check input.Length() >= sha256.Size before calling VerifyAndStrip.
  2. Delete the corrupted cache entry so it is re-fetched/regenerated.
  3. Verify the data producer actually appends the HMAC trailer (same kopia format version).

Example fix

// before
err := hmac.VerifyAndStrip(data, secret, out)
// after
if data.Length() < sha256.Size {
    return errors.New("cache entry truncated, refetching")
}
err := hmac.VerifyAndStrip(data, secret, out)
Defensive patterns

Strategy: validation

Validate before calling

if data.Length() < sha256.Size {
    return errors.New("blob too short to contain HMAC trailer")
}
return hmac.VerifyAndStrip(data, secret, out)

Try / catch

err := hmac.VerifyAndStrip(data, secret, out)
if err != nil && strings.Contains(err.Error(), "too short") {
    // treat as corrupt cache entry: delete and refetch
    return refetchBlob(id)
}

Prevention

When it happens

Trigger: Calling VerifyAndStrip (via hmac.Verify or when reading blobs from cache) with a buffer shorter than 32 bytes — e.g. an empty/truncated cache entry, a ciphertext blob that lost its trailing signature, or reading the wrong file/offset.

Common situations: Corrupted or partially written cache files on disk; a changed storage format or version mismatch where the HMAC trailer is absent; misconfigured cache directory containing foreign files.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/b882407051f6f5bc. Report an issue: GitHub.

Appendix: source

Thrown at internal/hmac/hmac.go:29

	"github.com/kopia/kopia/internal/gather"
)

// Append computes HMAC-SHA256 checksum for a given block of bytes and appends it.
func Append(input gather.Bytes, secret []byte, output *gather.WriteBuffer) {
	h := hmac.New(sha256.New, secret)

	input.WriteTo(output) //nolint:errcheck
	input.WriteTo(h)      //nolint:errcheck

	var hash [sha256.Size]byte

	output.Write(h.Sum(hash[:0])) //nolint:errcheck
}

// VerifyAndStrip verifies that given block of bytes has correct HMAC-SHA256 checksum and strips it.
func VerifyAndStrip(input gather.Bytes, secret []byte, output *gather.WriteBuffer) error {
	if input.Length() < sha256.Size {
		return errors.New("invalid data - too short")
	}

	p := input.Length() - sha256.Size

	h := hmac.New(sha256.New, secret)
	r := input.Reader()

	if _, err := io.CopyN(io.MultiWriter(h, output), r, int64(p)); err != nil {
		return errors.Wrap(err, "error hashing")
	}

	var sigBuf, actualSignature [sha256.Size]byte

	validSignature := h.Sum(sigBuf[:0])

	n, err := r.Read(actualSignature[:])
	if err != nil || n != sha256.Size {
		return errors.Wrap(err, "error reading signature")

View on GitHub (pinned to 82495e54b5)