{"record":{"id":"5c8a3bc957bfe0d0","repo":"AlistGo/alist","slug":"doubao-new-block-checksum-mismatch-seq-d-offse","errorCode":null,"errorMessage":"[doubao_new] block checksum mismatch: seq=%d offset=%d adler32=%s step2=%s","messagePattern":"\\[doubao_new\\] block checksum mismatch: seq=(.+?) offset=(.+?) adler32=(.+?) step2=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao_new/driver.go","lineNumber":361,"sourceCode":"\t\t\tif _, ok := blockMeta[item.Seq]; !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] missing block meta for seq %d\", item.Seq)\n\t\t\t}\n\t\t\tif item.Size <= 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] invalid block size from needed list: seq=%d size=%d\", item.Seq, item.Size)\n\t\t\t}\n\t\t\toffset := int64(item.Seq) * blockSize\n\t\t\tbuf := make([]byte, int(item.Size))\n\t\t\tn, err := tmpFile.ReadAt(buf, offset)\n\t\t\tif err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif n != len(buf) {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] short read: seq=%d want=%d got=%d\", item.Seq, len(buf), n)\n\t\t\t}\n\t\t\tbuf = buf[:n]\n\t\t\trealAdler := adler32String(buf)\n\t\t\tif realAdler != item.Checksum {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] block checksum mismatch: seq=%d offset=%d adler32=%s step2=%s\", item.Seq, offset, realAdler, item.Checksum)\n\t\t\t}\n\t\t\tpayloadStart := groupBuf.Len()\n\t\t\tgroupBuf.Write(buf)\n\t\t\tpayloadEnd := groupBuf.Len()\n\t\t\tpayloadAdler := adler32String(groupBuf.Bytes()[payloadStart:payloadEnd])\n\t\t\tif payloadAdler != item.Checksum {\n\t\t\t\treturn 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)\n\t\t\t}\n\t\t\tgroupSeqs = append(groupSeqs, item.Seq)\n\t\t\tgroupChecksums = append(groupChecksums, item.Checksum)\n\t\t\tgroupSizes = append(groupSizes, item.Size)\n\t\t\tgroupRealSize += int64(n)\n\t\t\tgroupExpectSum += item.Size\n\t\t\tif len(groupSeqs) >= maxMergeBlockCount {\n\t\t\t\tif err := flushGroup(); err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao_new/driver.go#L343-L379","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Retry with a stable, unchanging source file (copy to a temp location first if the original is being written)","Compare the reported adler32 values — if the local hash matches a DIFFERENT block of the same file, suspect offset arithmetic and report upstream","Exclude the OpenList temp directory from antivirus/backup scanners","Check filesystem/disk health if corruption is random across files","Re-run upload; transient corruption from disk-full conditions clears after space is freed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// hash the source region once before upload and pin it\nwant := adler32String(readAt(src, offset, size))\nif want != item.Checksum {\n    return fmt.Errorf(\"source block changed since prep: seq=%d\", item.Seq)\n}","typeGuard":null,"tryCatchPattern":"if err := checkBlock(...); err != nil && strings.Contains(err.Error(), \"block checksum mismatch\") {\n    // source may be mutating; fail with a clear cause instead of looping\n    return fmt.Errorf(\"source file unstable at seq %d: %w\", item.Seq, err)\n}","preventionTips":["Upload immutable copies of actively-written files","Keep antivirus/backup scanners away from spool directories","A local hash equal to a NEIGHBOR block's checksum signals offset math bugs — report it"],"tags":["doubao-new","upload","adler32","checksum","integrity","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}