{"record":{"id":"33fc7c99ced77e0a","repo":"AlistGo/alist","slug":"streamtape-upload-failed-http-d","errorCode":null,"errorMessage":"streamtape upload failed: http %d","messagePattern":"streamtape upload failed: http (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/streamtape/driver.go","lineNumber":356,"sourceCode":"\tvar uploadURL uploadURLResult\n\tif err := d.callAPI(ctx, \"/file/ul\", params, &uploadURL); err != nil {\n\t\treturn nil, err\n\t}\n\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\tSetFileReader(\"file1\", file.GetName(), reader).\n\t\tPost(uploadURL.URL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif res.StatusCode() >= http.StatusBadRequest {\n\t\treturn nil, fmt.Errorf(\"streamtape upload failed: http %d\", res.StatusCode())\n\t}\n\n\tuploadedID := extractFileIDFromUploadBody(res.Body())\n\tif uploadedID == \"\" {\n\t\tlist, listErr := d.List(ctx, &model.Object{ID: encodeFolderID(folderID), IsFolder: true}, model.ListArgs{})\n\t\tif listErr == nil {\n\t\t\tfor _, obj := range list {\n\t\t\t\tif obj.IsDir() {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif obj.GetName() == file.GetName() && (file.GetSize() <= 0 || obj.GetSize() == file.GetSize()) {\n\t\t\t\t\treturn obj, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn &model.Object{\n\t\t\tName:     file.GetName(),\n\t\t\tSize:     file.GetSize(),","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/streamtape/driver.go#L338-L374","documentation":"After obtaining a Streamtape upload slot and POSTing the file to the returned upload URL, the response status was >= 400. The status code is printed. Streamtape's upload endpoint is separate from its API and returns its own errors (invalid upload slot, size limit, server capacity).","triggerScenarios":"The presigned upload URL expired before the POST completed; file exceeds Streamtape's maximum size for the account; the upload slot was consumed by a previous attempt; Streamtape upload servers returning 5xx under load.","commonSituations":"Slow upstream connections letting the slot expire mid-upload; retrying an upload reusing a stale URL; free-tier size limits; Streamtape upload-node outages.","solutions":["Retry the upload from scratch — a fresh upload URL is fetched each attempt","Check the file size against Streamtape's current limits for the account tier","For large files on slow links, verify bandwidth/stability first, since slot expiry is time-based","If 5xx persists, check Streamtape status pages and retry later"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// check size against Streamtape limits before uploading (free tier: no file > ~limit)\nif streamtapeMaxSize > 0 && file.GetSize() > streamtapeMaxSize {\n    return fmt.Errorf(\"file exceeds Streamtape size limit\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    var code int\n    if n, _ := fmt.Sscanf(err.Error(), \"streamtape upload failed: http %d\", &code); n == 1 {\n        if code >= 500 || code == 429 { return retryUploadWithFreshURL() }\n    }\n    return err\n}","preventionTips":["Retry uploads from scratch — each attempt gets a fresh presigned URL","Verify file size against the account tier's limit before starting","Ensure stable bandwidth for large files; upload slots are time-limited"],"tags":["streamtape","upload","http"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}