AlistGo/alist · error

[doubao_new] block checksum mismatch: seq=%d offset=%d adler

Error message

[doubao_new] block checksum mismatch: seq=%d offset=%d adler32=%s step2=%s

What it means

First of two adler32 integrity checks in doubao_new: the block bytes just read from the spool (seq at offset seq*blockSize) hash to a different adler32 than the server-provided item.Checksum. The local file content does not match what the server expects for that dedup block — local corruption or wrong offset.

Source

Thrown at drivers/doubao_new/driver.go:361

			if _, ok := blockMeta[item.Seq]; !ok {
				return nil, fmt.Errorf("[doubao_new] missing block meta for seq %d", item.Seq)
			}
			if item.Size <= 0 {
				return nil, fmt.Errorf("[doubao_new] invalid block size from needed list: seq=%d size=%d", item.Seq, item.Size)
			}
			offset := int64(item.Seq) * blockSize
			buf := make([]byte, int(item.Size))
			n, err := tmpFile.ReadAt(buf, offset)
			if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
				return nil, err
			}
			if n != len(buf) {
				return nil, fmt.Errorf("[doubao_new] short read: seq=%d want=%d got=%d", item.Seq, len(buf), n)
			}
			buf = buf[:n]
			realAdler := adler32String(buf)
			if realAdler != item.Checksum {
				return nil, fmt.Errorf("[doubao_new] block checksum mismatch: seq=%d offset=%d adler32=%s step2=%s", item.Seq, offset, realAdler, item.Checksum)
			}
			payloadStart := groupBuf.Len()
			groupBuf.Write(buf)
			payloadEnd := groupBuf.Len()
			payloadAdler := adler32String(groupBuf.Bytes()[payloadStart:payloadEnd])
			if payloadAdler != item.Checksum {
				return nil, fmt.Errorf("[doubao_new] payload checksum mismatch: seq=%d start=%d end=%d adler32=%s step2=%s", item.Seq, payloadStart, payloadEnd, payloadAdler, item.Checksum)
			}
			groupSeqs = append(groupSeqs, item.Seq)
			groupChecksums = append(groupChecksums, item.Checksum)
			groupSizes = append(groupSizes, item.Size)
			groupRealSize += int64(n)
			groupExpectSum += item.Size
			if len(groupSeqs) >= maxMergeBlockCount {
				if err := flushGroup(); err != nil {
					return nil, err
				}
			}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Retry with a stable, unchanging source file (copy to a temp location first if the original is being written)
  2. Compare the reported adler32 values — if the local hash matches a DIFFERENT block of the same file, suspect offset arithmetic and report upstream
  3. Exclude the OpenList temp directory from antivirus/backup scanners
  4. Check filesystem/disk health if corruption is random across files
  5. Re-run upload; transient corruption from disk-full conditions clears after space is freed
Defensive patterns

Strategy: validation

Validate before calling

// hash the source region once before upload and pin it
want := adler32String(readAt(src, offset, size))
if want != item.Checksum {
    return fmt.Errorf("source block changed since prep: seq=%d", item.Seq)
}

Try / catch

if err := checkBlock(...); err != nil && strings.Contains(err.Error(), "block checksum mismatch") {
    // source may be mutating; fail with a clear cause instead of looping
    return fmt.Errorf("source file unstable at seq %d: %w", item.Seq, err)
}

Prevention

When it happens

Trigger: ReadAt returned full-length bytes but content differs — spool file corrupted on disk, source file modified between spooling and reading, offset math pointing at the wrong region, or the server's checksum list belonging to a different file version (dedup hit on a different file).

Common situations: Uploading a file being actively rewritten, bit-rot or aggressive 'optimizing' antivirus/proxy touching spool files, concurrent uploads of same-named different-content files, or driver offset bug after blockSize changes.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/5c8a3bc957bfe0d0. Report an issue: GitHub.