psf/requests · error · UnrewindableBodyError
An error occurred when rewinding request body for redirect.
Error message
An error occurred when rewinding request body for redirect.
What it means
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.
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.
Example fix
# before
with open('upload.bin', 'rb') as f:
resp = session.post(url, data=f) # UnrewindableBodyError on redirect
# after — read into memory
with open('upload.bin', 'rb') as f:
data = f.read()
resp = session.post(url, data=data) Defensive patterns
Strategy: fallback
Validate before calling
# Read body into memory before a redirecting request
with open(path, 'rb') as f:
body = f.read()
resp = session.post(url, data=body) # bytes are trivially re-readable Try / catch
try:
resp = session.post(url, data=file_obj)
except requests.exceptions.UnrewindableBodyError:
# Fallback: read into memory and retry
file_obj.seek(0)
resp = session.post(url, data=file_obj.read(), allow_redirects=True) Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of psf/requests@8068356288 (2026-08-11).
Data as JSON: /api/errors/a3498989f4bc6eba.
Report an issue: GitHub.
Appendix: source
Thrown at src/requests/utils.py:1151
netloc = netloc.rsplit("@", 1)[-1]
return urlunparse((scheme, netloc, path, params, query, ""))
def rewind_body(prepared_request: PreparedRequest) -> None:
"""Move file pointer back to its recorded starting position
so it can be read again on redirect.
"""
body_seek = getattr(prepared_request.body, "seek", None)
if body_seek is not None and isinstance(
prepared_request._body_position,
integer_types,
):
try:
body_seek(prepared_request._body_position)
except OSError:
raise UnrewindableBodyError(
"An error occurred when rewinding request body for redirect."
)
else:
raise UnrewindableBodyError("Unable to rewind request body for redirect.")
View on GitHub (pinned to 8068356288)