openai/openai-python · error · OpenAIError

Bedrock SigV4 authentication requires a replayable request b

Error message

Bedrock SigV4 authentication requires a replayable request body. Buffer the body before sending or use bearer authentication.

What it means

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.

Source

Thrown at src/openai/providers/bedrock.py:120

def _default_bedrock_base_url(endpoint: BedrockEndpoint, region: str) -> httpx2.URL:
    hostname = (
        f"bedrock-runtime.{region}.{_runtime_dns_suffixes(region)[0]}"
        if endpoint == "runtime"
        else f"bedrock-mantle.{region}.api.aws"
    )
    return _normalize_base_url(f"https://{hostname}/openai/v1")


def _same_origin(left: httpx2.URL, right: httpx2.URL) -> bool:
    return (left.scheme, left.host, left.port) == (right.scheme, right.host, right.port)


def _body_for_signing(request: httpx2.Request) -> bytes:
    try:
        return request.content
    except request_not_read_exceptions() as exc:
        raise OpenAIError(
            "Bedrock SigV4 authentication requires a replayable request body. "
            "Buffer the body before sending or use bearer authentication."
        ) from exc


def _assert_provider_owns_authorization(request: httpx2.Request) -> None:
    if "Authorization" in request.headers:
        raise OpenAIError("Bedrock provider authentication cannot be combined with a custom `Authorization` header.")


def _without_redirects(options: FinalRequestOptions) -> FinalRequestOptions:
    if options.follow_redirects:
        raise OpenAIError(
            "Bedrock SigV4 authentication does not support automatic redirects. "
            "Send a new request to the redirect target so it can be signed again."
        )
    options.follow_redirects = False
    return options

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Buffer the request body before sending (pass bytes, not a stream).
  2. Or switch the Bedrock provider to bearer authentication (AWS_BEARER_TOKEN_BEDROCK / bearer provider), which does not need to hash the body.

Example fix

# before
content = some_file  # streamed body
await client.post(..., content=stream)

# after
body = some_file.read()  # bytes
await client.post(..., content=body)
Defensive patterns

Strategy: fallback

Validate before calling

# before sending, ensure bodies are bytes
body = data if isinstance(data, (bytes, bytearray)) else json.dumps(data).encode()

Type guard

def is_replayable_body(body: object) -> bool:
    return isinstance(body, (bytes, bytearray, str)) or hasattr(body, "read")

Try / catch

try:
    resp = client.responses.create(**payload)
except OpenAIError as e:
    if "replayable request body" in str(e):
        payload = {**payload, "content": buffered_bytes}
        resp = client.responses.create(**payload)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: Large file uploads streamed rather than buffered; a custom httpx2 transport wrapping the body in a generator; middleware that converts bodies to streams.

Understand the failure class

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/009596a218a95af9. Report an issue: GitHub.