{"record":{"id":"72616d485068b665","repo":"AlistGo/alist","slug":"wukong-get-upload-candidates-failed-s","errorCode":null,"errorMessage":"wukong get upload candidates failed: %s","messagePattern":"wukong get upload candidates failed: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/wukong/driver.go","lineNumber":426,"sourceCode":"\t}\n\tif resp.Code != 0 {\n\t\treturn nil, fmt.Errorf(\"wukong get upload auth token failed: code=%d message=%s\", resp.Code, resp.Message)\n\t}\n\treturn &resp, nil\n}\n\nfunc (d *Wukong) getUploadCandidates(ctx context.Context, auth *uploadAuthTokenResp) (*getUploadCandidatesResp, error) {\n\tq := map[string]string{\n\t\t\"Action\":    \"GetUploadCandidates\",\n\t\t\"Version\":   \"2020-11-19\",\n\t\t\"SpaceName\": videoSpaceName,\n\t}\n\tvar resp getUploadCandidatesResp\n\tif err := d.vodRequest(ctx, http.MethodGet, q, nil, auth, &resp); err != nil {\n\t\treturn nil, err\n\t}\n\tif resp.ResponseMetadata.Error.Code != \"\" {\n\t\treturn nil, fmt.Errorf(\"wukong get upload candidates failed: %s\", resp.ResponseMetadata.Error.Message)\n\t}\n\treturn &resp, nil\n}\n\nfunc (d *Wukong) applyUploadInner(ctx context.Context, auth *uploadAuthTokenResp, uploadType string, fileSize int64, bestHosts string) (*applyUploadInnerResp, error) {\n\tspaceName := auth.SpaceName\n\tif uploadType == \"video\" {\n\t\tspaceName = videoSpaceName\n\t}\n\tq := map[string]string{\n\t\t\"Action\":          \"ApplyUploadInner\",\n\t\t\"Version\":         \"2020-11-19\",\n\t\t\"SpaceName\":       spaceName,\n\t\t\"FileType\":        uploadType,\n\t\t\"IsInner\":         \"1\",\n\t\t\"ClientBestHosts\": bestHosts,\n\t\t\"NeedFallback\":    \"true\",\n\t\t\"FileSize\":        strconv.FormatInt(fileSize, 10),","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/wukong/driver.go#L408-L444","documentation":"Thrown by getUploadCandidates after a signed GET (Action=GetUploadCandidates, SpaceName=wukong_netdisk_ugc) against vod.bytedanceapi.com. The VOD response metadata carries a non-empty Error.Code, so the driver surfaces Error.Message. This call selects upload hosts/candidates and precedes ApplyUploadInner.","triggerScenarios":"The VOD security token from auth_token is expired or scoped to a different space; SpaceName wukong_netdisk_ugc is not authorized for the account; signature (AWS-style x-amz signing) mismatch due to clock skew; upstream VOD service error.","commonSituations":"Slow uploads where the token expired between minting and candidate selection; system clock out of sync breaking x-amz-date signing; Wukong backend changing the video space name; regional VOD outage.","solutions":["Refresh the upload auth token (re-run getUploadAuthToken) and retry candidates once","Sync system clock (NTP) so the x-amz-date signature is valid","Confirm the account can upload videos in the Wukong web UI, proving the space is enabled","If Error.Message mentions signature/auth, re-login entirely and restart the Put"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"cand, err := d.getUploadCandidates(ctx, auth)\nif err != nil {\n    if strings.Contains(err.Error(), \"Signature\") || strings.Contains(err.Error(), \"Token\") {\n        auth, aerr := d.getUploadAuthToken(ctx, uploadType)\n        if aerr == nil {\n            cand, err = d.getUploadCandidates(ctx, auth)\n        }\n    }\n    if err != nil { return err }\n}","preventionTips":["Keep system clocks NTP-synced for x-amz-date signature validity","Refresh the token when any VOD action reports signature/token errors, then retry once","Treat candidates+apply as one unit: never reuse a token from a previous session"],"tags":["wukong","upload","vod","get-upload-candidates","signing","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}