diff --git a/litellm/llms/bedrock/base_aws_llm.py b/litellm/llms/bedrock/base_aws_llm.py index 30119b9810e..b159d62367d 100644 --- a/litellm/llms/bedrock/base_aws_llm.py +++ b/litellm/llms/bedrock/base_aws_llm.py @@ -1268,7 +1268,8 @@ class BaseAWSLLM: # Add back all original headers (including forwarded ones) after signature calculation for header_name, header_value in headers.items(): - request.headers[header_name] = header_value + if header_value is not None: + request.headers[header_name] = header_value if ( extra_headers is not None and "Authorization" in extra_headers @@ -1395,7 +1396,8 @@ class BaseAWSLLM: # Add back original headers after signing. Only headers in SignedHeaders # are integrity-protected; forwarded headers (x-forwarded-*) must remain unsigned. for header_name, header_value in headers.items(): - request_headers_dict[header_name] = header_value + if header_value is not None: + request_headers_dict[header_name] = header_value if ( headers is not None and "Authorization" in headers ): # prevent sigv4 from overwriting the auth header diff --git a/tests/test_litellm/llms/bedrock/test_base_aws_llm.py b/tests/test_litellm/llms/bedrock/test_base_aws_llm.py index 8871bff537d..29ed345d2de 100644 --- a/tests/test_litellm/llms/bedrock/test_base_aws_llm.py +++ b/tests/test_litellm/llms/bedrock/test_base_aws_llm.py @@ -1556,6 +1556,9 @@ def test_sign_request_with_none_header_values(): This reproduces the Bedrock KB GovCloud issue where SigV4 signing failed with 'NoneType' object has no attribute 'split'. + + Also verifies that None-valued headers are NOT re-merged into the + returned headers dict (which would cause downstream HTTP client failures). """ llm = BaseAWSLLM() @@ -1564,6 +1567,7 @@ def test_sign_request_with_none_header_values(): headers_with_nones = { "Content-Type": "application/json", "x-amzn-trace-id": None, + "x-forwarded-for": None, } with patch.object( @@ -1586,6 +1590,12 @@ def test_sign_request_with_none_header_values(): assert "Authorization" in result_headers assert result_body is not None + # None-valued headers must NOT appear in the returned headers + for header_name, header_value in result_headers.items(): + assert header_value is not None, ( + f"Header '{header_name}' has None value in returned headers" + ) + def test_is_already_running_as_role_ssl_verify_passed(): """