{"record":{"id":"a32180daaa49e780","repo":"AlistGo/alist","slug":"upload-failed-http-d","errorCode":null,"errorMessage":"upload failed: http %d","messagePattern":"upload failed: http (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/darkibox/driver.go","lineNumber":261,"sourceCode":"\t// Step 2: Upload the file to the upload server\n\treader := driver.NewLimitedUploadStream(ctx, &driver.ReaderUpdatingProgress{\n\t\tReader:         file,\n\t\tUpdateProgress: up,\n\t})\n\n\tres, err := base.RestyClient.R().\n\t\tSetContext(ctx).\n\t\tSetMultipartField(\"file\", file.GetName(), \"\", reader).\n\t\tSetMultipartFormData(map[string]string{\n\t\t\t\"key\":    d.APIKey,\n\t\t\t\"fld_id\": fldIDStr(folderID),\n\t\t}).\n\t\tPost(server.URL)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"upload failed: %w\", err)\n\t}\n\tif res.StatusCode() != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"upload failed: http %d\", res.StatusCode())\n\t}\n\n\t// Try to parse upload response to get the file code\n\tvar uploadResp uploadResult\n\tif err := base.RestyClient.JSONUnmarshal(res.Body(), &uploadResp); err == nil && len(uploadResp.Files) > 0 {\n\t\tuf := uploadResp.Files[0]\n\t\treturn &model.Object{\n\t\t\tID:       encodeFileID(uf.FileCode),\n\t\t\tName:     file.GetName(),\n\t\t\tSize:     file.GetSize(),\n\t\t\tIsFolder: false,\n\t\t}, nil\n\t}\n\n\treturn &model.Object{\n\t\tName:     file.GetName(),\n\t\tSize:     file.GetSize(),\n\t\tIsFolder: false,","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/darkibox/driver.go#L243-L279","documentation":"The POST to the upload server completed but returned an HTTP status other than 200. The response body is not included in the message, so the provider's explanation (auth failure, quota, size limit) is lost. Common codes: 401/403 (bad key), 413 (file too large), 5xx (server-side failure).","triggerScenarios":"Upload server rejects the multipart request: expired API key sent in the 'key' form field, file exceeds the account's size cap (413), invalid fld_id (404/400), or upload server overloaded (502/503).","commonSituations":"Free-tier accounts hitting max file size; key revoked between /upload/server and the POST; folder ID from a stale listing deleted server-side.","solutions":["Map the status: 401/403 → refresh API key; 413 → split or compress the file / upgrade plan; 5xx → retry later","Include res.Body() in the error (see exampleFix) so the provider's message is visible next time","Verify fld_id still exists by listing the destination folder"],"exampleFix":"// before\nif res.StatusCode() != http.StatusOK {\n\treturn nil, fmt.Errorf(\"upload failed: http %d\", res.StatusCode())\n}\n// after\nif res.StatusCode() != http.StatusOK {\n\treturn nil, fmt.Errorf(\"upload failed: http %d: %s\", res.StatusCode(), strings.TrimSpace(string(res.Body())))\n}","handlingStrategy":"try-catch","validationCode":"if file.GetSize() > d.maxFileSize() { // query provider limit\n\treturn errors.New(\"file exceeds provider size limit\")\n}","typeGuard":null,"tryCatchPattern":"var httpErr matcher // extract code from \"upload failed: http %d\"\nif m := regexp.MustCompile(`upload failed: http (\\d+)`).FindStringSubmatch(err.Error()); m != nil {\n\tswitch m[1] {\n\tcase \"401\", \"403\": reconfigureKey()\n\tcase \"413\": splitOrCompress()\n\tcase \"502\", \"503\": retryLater()\n\t}\n}","preventionTips":["Know the account's max file size before uploading","Keep the API key valid for the whole upload session","Treat 5xx as retryable, 4xx as configuration issues"],"tags":["darkibox","upload","http-status","storage-driver"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}