AlistGo/alist · error

wukong init multipart upload failed: code=%d message=%s

Error message

wukong init multipart upload failed: code=%d message=%s

What it means

Thrown by initMultipartUpload when POSTing phase=init to https://<host>/upload/v1/<storeURI> returns a code other than 2000. The TOS multipart session could not be created, so no UploadID exists and the whole multipart transfer aborts before any part is sent.

Source

Thrown at drivers/wukong/driver.go:658

		SetHeader("Host", host).
		SetHeader("Referer", webReferer).
		SetHeader("Origin", "https://pan.wkbrowser.com").
		SetHeader("Authorization", auth).
		SetQueryParams(map[string]string{
			"uploadmode": "part",
			"phase":      "init",
		}).
		SetResult(&resp)
	if storageUser != "" {
		req.SetHeader("X-Storage-U", storageUser)
	}
	uploadURL := fmt.Sprintf("https://%s/upload/v1/%s", host, storeURI)
	_, err := req.Post(uploadURL)
	if err != nil {
		return "", err
	}
	if resp.Code != minUploadSubmitSuccess {
		return "", fmt.Errorf("wukong init multipart upload failed: code=%d message=%s", resp.Code, resp.Message)
	}
	if resp.Data.UploadID == "" {
		return "", errors.New("wukong init multipart upload returns empty uploadid")
	}
	return resp.Data.UploadID, nil
}

func (d *Wukong) uploadMultipartPart(ctx context.Context, host, storeURI, auth, storageUser, uploadID string, partNumber int, data []byte, crc32Hex string) (string, error) {
	var resp tosUploadResp
	req := base.NewRestyClient().R().
		SetContext(ctx).
		SetHeader("Host", host).
		SetHeader("Referer", webReferer).
		SetHeader("Origin", "https://pan.wkbrowser.com").
		SetHeader("Authorization", auth).
		SetHeader("Content-Type", "application/octet-stream").
		SetHeader("Content-Crc32", crc32Hex).
		SetHeader("Content-Length", strconv.Itoa(len(data))).

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-run applyUploadInner to obtain fresh StoreURI, hosts, and Authorization, then init again
  2. Verify resp handles the empty-UploadID guard: if code is 2000 but UploadID is empty, that is a separate error — report upstream
  3. Retry against a different host from the candidates list
  4. Check that the file size actually requires multipart (totalParts > 0) before initializing
Defensive patterns

Strategy: retry

Validate before calling

if size <= 0 {
    return errors.New("multipart init aborted: non-positive file size")
}

Try / catch

uploadID, err := d.initMultipartUpload(ctx, host, storeURI, auth, storageUser)
if err != nil {
    if strings.Contains(err.Error(), "auth") || strings.Contains(err.Error(), "expire") {
        // fresh apply + init once
        return d.restartMultipart(ctx, tempFile, size)
    }
    return err
}

Prevention

When it happens

Trigger: Authorization from ApplyUploadInner expired or not valid for multipart; storeURI malformed; selected upload host rejecting the init; X-Storage-U required but missing; upstream TOS outage.

Common situations: Upload started long after applyUploadInner (token TTL passed); best-host list stale; a previous upload's auth being reused after a driver retry.

Related errors


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