AlistGo/alist · critical

wukong upload to tos crc32 mismatch: local=%s remote=%s

Error message

wukong upload to tos crc32 mismatch: local=%s remote=%s

What it means

Thrown by uploadToTOS when the TOS endpoint returns a Crc32 that does not match the locally computed IEEE CRC32 of the uploaded body. The server is explicitly reporting that the bytes it stored differ from the bytes sent — a data-integrity failure detected end-to-end.

Source

Thrown at drivers/wukong/driver.go:592

		SetHeader("Authorization", auth).
		SetHeader("Content-Type", "application/octet-stream").
		SetHeader("Content-Crc32", crc32Hex).
		SetHeader("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, url.QueryEscape(fileName))).
		SetHeader("Content-Length", strconv.FormatInt(size, 10)).
		SetBody(body).
		SetResult(&resp)
	if storageUser != "" {
		req.SetHeader("X-Storage-U", storageUser)
	}
	_, err := req.Post(uploadURL)
	if err != nil {
		return err
	}
	if resp.Code != minUploadSubmitSuccess {
		return fmt.Errorf("wukong upload to tos failed: code=%d message=%s", resp.Code, resp.Message)
	}
	if resp.Data.Crc32 != "" && !strings.EqualFold(resp.Data.Crc32, crc32Hex) {
		return fmt.Errorf("wukong upload to tos crc32 mismatch: local=%s remote=%s", crc32Hex, resp.Data.Crc32)
	}
	return nil
}

func (d *Wukong) uploadToTOSMultipart(ctx context.Context, host, storeURI, auth, storageUser string, tempFile model.File, size int64, up driver.UpdateProgress) error {
	uploadID, err := d.initMultipartUpload(ctx, host, storeURI, auth, storageUser)
	if err != nil {
		return err
	}

	totalParts := int((size + multipartChunkSize - 1) / multipartChunkSize)
	if totalParts <= 0 {
		return errors.New("invalid multipart parts")
	}
	parts := make([]string, 0, totalParts)
	for i := 0; i < totalParts; i++ {
		partNumber := i + 1
		offset := int64(i) * multipartChunkSize

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Retry the upload from a freshly cached temp file (re-run CacheFullInTempFile) with a new upload session
  2. Verify local file integrity (compare md5 before upload) to rule out source corruption
  3. Bypass intermediaries (proxy, AV TLS inspection) that could mutate the body
  4. If persistent for one environment but not others, capture the sent body hash server-side and report upstream
Defensive patterns

Strategy: retry

Validate before calling

// verify local integrity before upload
h := crc32.NewIEEE()
if f, ok := tempFile.(io.Reader); ok {
    io.Copy(h, f) // tempFile must support re-read; else use stored hash
}
localCRC := fmt.Sprintf("%08x", h.Sum32())

Try / catch

if err := d.uploadToTOS(...); err != nil {
    if strings.Contains(err.Error(), "crc32 mismatch") {
        // data corrupted in transit/cache: full clean retry with fresh session
        return d.restartAndUpload(ctx)
    }
    return err
}

Prevention

When it happens

Trigger: Client-side body corruption (truncated temp file, concurrent write to the cached temp file); transparent modification by a proxy/AV scanning middlebox; server-side bug returning the wrong CRC; memory/disk corruption on the host.

Common situations: CacheFullInTempFile raced with another writer; flaky NIC or disk producing bit errors; corporate proxy re-encoding the body; rare server-side mismatch after retries.

Related errors


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