juicedata/juicefs · critical

verify checksum failed: %d != %d

Error message

verify checksum failed: %d != %d

What it means

checksumReader transparently CRC32C-checksums data as it streams from object storage. When the stream ends (io.EOF) or the expected remaining length is consumed, the running checksum must equal the expected value recorded by the writer; otherwise the data was corrupted in transit/storage and Read returns this error with the computed vs expected CRC values.

Source

Thrown at pkg/object/checksum.go:68

		}
	}
	return strconv.Itoa(int(hash))
}

type checksumReader struct {
	io.ReadCloser
	expected        uint32
	checksum        uint32
	remainingLength int64
	table           *crc32.Table
}

func (c *checksumReader) Read(buf []byte) (n int, err error) {
	n, err = c.ReadCloser.Read(buf)
	c.checksum = crc32.Update(c.checksum, c.table, buf[:n])
	c.remainingLength -= int64(n)
	if (err == io.EOF || c.remainingLength == 0) && c.checksum != c.expected {
		return 0, fmt.Errorf("verify checksum failed: %d != %d", c.checksum, c.expected)
	}
	return
}
func verifyChecksum(in io.ReadCloser, checksum string, contentLength int64) io.ReadCloser {
	return verifyChecksum0(in, checksum, contentLength, crc32c)
}
func verifyChecksum0(in io.ReadCloser, checksum string, contentLength int64, table *crc32.Table) io.ReadCloser {
	if checksum == "" {
		return in
	}
	expected, err := strconv.Atoi(checksum)
	if err != nil {
		logger.Errorf("invalid crc32c: %s", checksum)
		return in
	}
	return &checksumReader{in, uint32(expected), 0, contentLength, table}
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Re-upload/re-copy the affected object to restore a consistent checksum
  2. Verify the object in the bucket (compare CRC32C of downloaded bytes with stored metadata)
  3. Check object storage backend health/disk (SMART, scrubbing) for silent corruption
  4. If a proxy/cache sits between client and storage, disable it and retest to isolate the corruption point
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: verify object integrity proactively after writing
meta, _ := obj.Head(ctx, key)
// compare meta size/content-length with what you uploaded before reading back

Try / catch

// Go
data, err := obj.Get(ctx, key, 0, -1)
if err != nil && strings.Contains(err.Error(), "verify checksum failed") {
    // treat as corruption: re-upload object or fail the read loudly; never retry in place
}

Prevention

When it happens

Trigger: Reading an object whose uploaded content does not match its recorded checksum: bit rot in the object store, truncated upload, buggy third-party writer, or a corrupted cache layer feeding wrong bytes for the expected length.

Common situations: Network corruption between object storage and client; partial/multipart upload that was truncated; disk errors on storage node; mismatched checksum metadata after a manual object replacement in the bucket.

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 juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/10ca711cf3753229. Report an issue: GitHub.