{"record":{"id":"5159afc319bc3609","repo":"dutchcoders/transfer.sh","slug":"could-not-retrieve-file","errorCode":null,"errorMessage":"Could not retrieve file.","messagePattern":"Could not retrieve file\\.","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"server/handlers.go","lineNumber":1000,"sourceCode":"\t\ttoken := strings.Split(key, \"/\")[0]\n\t\tfilename := sanitize(strings.Split(key, \"/\")[1])\n\n\t\tif _, err := s.checkMetadata(r.Context(), token, filename, true); err != nil {\n\t\t\ts.logger.Printf(\"Error metadata: %s\", err.Error())\n\t\t\tcontinue\n\t\t}\n\n\t\treader, _, err := s.storage.Get(r.Context(), token, filename, nil)\n\t\tdefer storage.CloseCheck(reader)\n\n\t\tif err != nil {\n\t\t\tif s.storage.IsNotExist(err) {\n\t\t\t\thttp.Error(w, \"File not found\", 404)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ts.logger.Printf(\"%s\", err.Error())\n\t\t\thttp.Error(w, \"Could not retrieve file.\", http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\n\t\theader := &zip.FileHeader{\n\t\t\tName:   strings.Split(key, \"/\")[1],\n\t\t\tMethod: zip.Store,\n\n\t\t\tModified: time.Now().UTC(),\n\t\t}\n\n\t\tfw, err := zw.CreateHeader(header)\n\n\t\tif err != nil {\n\t\t\ts.logger.Printf(\"%s\", err.Error())\n\t\t\thttp.Error(w, \"Internal server error.\", http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n","sourceCodeStart":982,"sourceCodeEnd":1018,"githubUrl":"https://github.com/dutchcoders/transfer.sh/blob/c37bfd95797fd6da8a6da53fc13d191994b3f687/server/handlers.go#L982-L1018","documentation":"When s.storage.Get fails with any error other than not-exist, zipHandler logs it and returns HTTP 500 'Could not retrieve file.'. The storage backend failed to open/read the object for an infrastructural reason rather than because the file is absent.","triggerScenarios":"s.storage.Get returns a non-IsNotExist error: backend unreachable, invalid credentials, permission denied on the file/directory, context deadline exceeded, or disk I/O error while opening the object.","commonSituations":"S3/GCS credentials rotated or revoked; storage volume full or failing; firewall blocking the object-store endpoint; client disconnecting and canceling the request before Get completed.","solutions":["Inspect the server log line emitted just before the 500 — it contains the real backend error.","Validate storage backend credentials and network reachability from the server host.","Check filesystem permissions on the storage directory for the server process.","Retry the download; if correlated with timeouts, increase the storage client timeout."],"exampleFix":"// before\nhttp.Error(w, \"Could not retrieve file.\", http.StatusInternalServerError)\n// after\ns.logger.Printf(\"zip get %s/%s: %v\", token, filename, err)\nhttp.Error(w, \"Could not retrieve file.\", http.StatusInternalServerError)","handlingStrategy":"retry","validationCode":"// Check storage reachability before bulk archive downloads:\nresp, err := http.Get(healthEndpoint) // or HEAD a known file\nif err != nil { /* backend unreachable: GETs will 500 */ }","typeGuard":null,"tryCatchPattern":"// 500 on retrieve = backend error: retry with backoff, then check server logs\nfor i := 0; i < 3; i++ {\n    resp, err := download()\n    if err == nil && resp.StatusCode == 200 { break }\n    time.Sleep(backoff(i))\n}","preventionTips":["Monitor storage backend health (disk space, connectivity, credential validity).","Use generous storage client timeouts for large files.","Alert on server log lines preceding 500s — they carry the root cause.","Verify IAM/ACL permissions after any credential rotation."],"tags":["http-500","storage","io"],"backgroundTag":"storage-read-failed","analyzedSha":"c37bfd95797fd6da8a6da53fc13d191994b3f687","analyzedAt":"2026-09-05T10:21:07.548Z","contentChangedAt":"2026-09-05T10:21:07.548Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}