{"record":{"id":"a3498989f4bc6eba","repo":"psf/requests","slug":"an-error-occurred-when-rewinding-request-body-for","errorCode":null,"errorMessage":"An error occurred when rewinding request body for redirect.","messagePattern":"An error occurred when rewinding request body for redirect\\.","errorType":"exception","errorClass":"UnrewindableBodyError","httpStatus":null,"severity":"error","filePath":"src/requests/utils.py","lineNumber":1151,"sourceCode":"\n    netloc = netloc.rsplit(\"@\", 1)[-1]\n\n    return urlunparse((scheme, netloc, path, params, query, \"\"))\n\n\ndef rewind_body(prepared_request: PreparedRequest) -> None:\n    \"\"\"Move file pointer back to its recorded starting position\n    so it can be read again on redirect.\n    \"\"\"\n    body_seek = getattr(prepared_request.body, \"seek\", None)\n    if body_seek is not None and isinstance(\n        prepared_request._body_position,\n        integer_types,\n    ):\n        try:\n            body_seek(prepared_request._body_position)\n        except OSError:\n            raise UnrewindableBodyError(\n                \"An error occurred when rewinding request body for redirect.\"\n            )\n    else:\n        raise UnrewindableBodyError(\"Unable to rewind request body for redirect.\")\n","sourceCodeStart":1133,"sourceCodeEnd":1156,"githubUrl":"https://github.com/psf/requests/blob/8068356288978c4f54661ae6f95afe0e0831885e/src/requests/utils.py#L1133-L1156","documentation":"Raised by rewind_body() when the request body's seek() method exists and _body_position is recorded, but calling body.seek(position) raises an OSError. This happens during redirect handling when the session tries to rewind a file-like body so it can be re-read for the redirected request. The OSError typically means the underlying file/stream was closed, moved, or is no longer accessible.","triggerScenarios":"A POST/PUT with a file body that gets redirected, but the file handle was closed between the original request and the redirect; a seekable stream whose underlying resource was garbage-collected or closed; a file on a network mount that became unavailable.","commonSituations":"Uploading a file with redirects enabled where the file handle goes out of scope; using a temporary file that gets cleaned up; streaming from a pipe or subprocess that terminates before the redirect completes; file descriptor limits causing the handle to close.","solutions":["Read the body into memory before the request: pass data=open(path, 'rb').read() instead of the file object.","Keep the file handle alive for the duration of the request including redirects.","Disable redirects for the initial request and handle them manually, re-opening the file for each attempt."],"exampleFix":"# before\nwith open('upload.bin', 'rb') as f:\n    resp = session.post(url, data=f)  # UnrewindableBodyError on redirect\n\n# after — read into memory\nwith open('upload.bin', 'rb') as f:\n    data = f.read()\nresp = session.post(url, data=data)","handlingStrategy":"fallback","validationCode":"# Read body into memory before a redirecting request\nwith open(path, 'rb') as f:\n    body = f.read()\nresp = session.post(url, data=body)  # bytes are trivially re-readable","typeGuard":null,"tryCatchPattern":"try:\n    resp = session.post(url, data=file_obj)\nexcept requests.exceptions.UnrewindableBodyError:\n    # Fallback: read into memory and retry\n    file_obj.seek(0)\n    resp = session.post(url, data=file_obj.read(), allow_redirects=True)","preventionTips":["Read file bodies into memory (bytes) before posting if redirects are expected.","Keep file handles alive for the entire duration of requests including redirects.","Avoid passing file objects that may be closed by context managers or garbage collection.","Use allow_redirects=False for fragile file bodies and handle redirects manually."],"tags":["unrewindable-body","redirect","file-upload","body-seek","os-error"],"backgroundTag":null,"analyzedSha":"8068356288978c4f54661ae6f95afe0e0831885e","analyzedAt":"2026-08-11T20:11:09.238Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}