{"record":{"id":"009596a218a95af9","repo":"openai/openai-python","slug":"bedrock-sigv4-authentication-requires-a-replayable","errorCode":null,"errorMessage":"Bedrock SigV4 authentication requires a replayable request body. Buffer the body before sending or use bearer authentication.","messagePattern":"Bedrock SigV4 authentication requires a replayable request body\\. Buffer the body before sending or use bearer authentication\\.","errorType":"error_code","errorClass":"OpenAIError","httpStatus":null,"severity":"error","filePath":"src/openai/providers/bedrock.py","lineNumber":120,"sourceCode":"\ndef _default_bedrock_base_url(endpoint: BedrockEndpoint, region: str) -> httpx2.URL:\n    hostname = (\n        f\"bedrock-runtime.{region}.{_runtime_dns_suffixes(region)[0]}\"\n        if endpoint == \"runtime\"\n        else f\"bedrock-mantle.{region}.api.aws\"\n    )\n    return _normalize_base_url(f\"https://{hostname}/openai/v1\")\n\n\ndef _same_origin(left: httpx2.URL, right: httpx2.URL) -> bool:\n    return (left.scheme, left.host, left.port) == (right.scheme, right.host, right.port)\n\n\ndef _body_for_signing(request: httpx2.Request) -> bytes:\n    try:\n        return request.content\n    except request_not_read_exceptions() as exc:\n        raise OpenAIError(\n            \"Bedrock SigV4 authentication requires a replayable request body. \"\n            \"Buffer the body before sending or use bearer authentication.\"\n        ) from exc\n\n\ndef _assert_provider_owns_authorization(request: httpx2.Request) -> None:\n    if \"Authorization\" in request.headers:\n        raise OpenAIError(\"Bedrock provider authentication cannot be combined with a custom `Authorization` header.\")\n\n\ndef _without_redirects(options: FinalRequestOptions) -> FinalRequestOptions:\n    if options.follow_redirects:\n        raise OpenAIError(\n            \"Bedrock SigV4 authentication does not support automatic redirects. \"\n            \"Send a new request to the redirect target so it can be signed again.\"\n        )\n    options.follow_redirects = False\n    return options","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/openai/openai-python/blob/9917c6e28e66e90e1227b3d223c06a8c5441515a/src/openai/providers/bedrock.py#L102-L138","documentation":"SigV4 signing must hash the full request body, but request.content raised a 'not read' error, meaning the body is a streaming/ungot request whose bytes cannot be replayed. Because AWS SigV4 cannot sign an unreadable body, the provider raises this instead of sending an unsigned/unsignable request.","triggerScenarios":"Creating an OpenAI client whose httpx2 transport produces streaming request bodies (e.g. custom transport or file streaming) and issuing a request through the Bedrock SigV4 provider.","commonSituations":"Large file uploads streamed rather than buffered; a custom httpx2 transport wrapping the body in a generator; middleware that converts bodies to streams.","solutions":["Buffer the request body before sending (pass bytes, not a stream).","Or switch the Bedrock provider to bearer authentication (AWS_BEARER_TOKEN_BEDROCK / bearer provider), which does not need to hash the body."],"exampleFix":"# before\ncontent = some_file  # streamed body\nawait client.post(..., content=stream)\n\n# after\nbody = some_file.read()  # bytes\nawait client.post(..., content=body)","handlingStrategy":"fallback","validationCode":"# before sending, ensure bodies are bytes\nbody = data if isinstance(data, (bytes, bytearray)) else json.dumps(data).encode()","typeGuard":"def is_replayable_body(body: object) -> bool:\n    return isinstance(body, (bytes, bytearray, str)) or hasattr(body, \"read\")","tryCatchPattern":"try:\n    resp = client.responses.create(**payload)\nexcept OpenAIError as e:\n    if \"replayable request body\" in str(e):\n        payload = {**payload, \"content\": buffered_bytes}\n        resp = client.responses.create(**payload)\n    else:\n        raise","preventionTips":["Buffer file uploads into bytes before passing to the client when using SigV4.","Or configure bearer auth (AWS_BEARER_TOKEN_BEDROCK) which doesn't hash the body.","Avoid custom transports that convert request bodies to generators."],"tags":["bedrock","aws","sigv4","streaming-body"],"backgroundTag":"request-body-not-replayable","analyzedSha":"9917c6e28e66e90e1227b3d223c06a8c5441515a","analyzedAt":"2026-08-28T11:46:34.183Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}