The Fix
Fixes an issue where cookies with duplicate names but different domains or paths were being lost when updating the cookie jar. The root cause was that SimpleCookie uses only the cookie name as its key, causing later cookies with the same name to overwrite earlier ones.
Based on closed aio-libs/aiohttp issue #11105 · PR/commit linked
Production note: This usually shows up under retries/timeouts. Treat it as a side-effect risk until you can verify behavior with a canary + real traffic.
@@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
+Fixed an issue where cookies with duplicate names but different domains or paths
+were lost when updating the cookie jar. The :class:`~aiohttp.ClientSession`
+cookie jar now correctly stores all cookies even if they have the same name but
"""Test script."""
import asyncio
import base64
import secrets
import orjson
from aiohttp import ClientSession
# Amazon APP info
AMAZON_APP_BUNDLE_ID = "com.amazon.echo"
AMAZON_APP_ID = "MAPiOSLib/6.0/ToHideRetailLink"
AMAZON_APP_NAME = "AioAmazonDevices"
AMAZON_APP_VERSION = "2.2.556530.0"
AMAZON_DEVICE_SOFTWARE_VERSION = "35602678"
AMAZON_DEVICE_TYPE = "A2IVLV5VM2W81"
AMAZON_CLIENT_OS = "16.6"
DEFAULT_HEADERS = {
"User-Agent": (
f"Mozilla/5.0 (iPhone; CPU iPhone OS {AMAZON_CLIENT_OS.replace('.', '_')} like Mac OS X) " # noqa: E501
"AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
),
"Accept-Language": "en-US",
"Accept-Encoding": "gzip",
"Connection": "keep-alive",
}
URL = "https://www.amazon.it/ap/signin"
async def main() -> None:
"""Start script."""
session = ClientSession(
headers=DEFAULT_HEADERS,
cookies=await _build_init_cookies(),
)
resp = await session.request("POST", URL)
print("Cookies:")
print(resp.cookies)
print("--------")
print("Headers:")
print(resp.headers)
async def _build_init_cookies() -> dict[str, str]:
"""Build initial cookies to prevent captcha in most cases."""
token_bytes = secrets.token_bytes(313)
frc = base64.b64encode(token_bytes).decode("ascii").rstrip("=")
map_md_dict = {
"device_user_dictionary": [],
"device_registration_data": {
"software_version": AMAZON_DEVICE_SOFTWARE_VERSION,
},
"app_identifier": {
"app_version": AMAZON_APP_VERSION,
"bundle_id": AMAZON_APP_BUNDLE_ID,
},
}
map_md_str = orjson.dumps(map_md_dict).decode("utf-8")
map_md = base64.b64encode(map_md_str.encode()).decode().rstrip("=")
return {"amzn-app-id": AMAZON_APP_ID, "frc": frc, "map-md": map_md}
if __name__ == "__main__":
asyncio.run(main())
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Option A — Apply the official fix\nFixes an issue where cookies with duplicate names but different domains or paths were being lost when updating the cookie jar. The root cause was that SimpleCookie uses only the cookie name as its key, causing later cookies with the same name to overwrite earlier ones.\nWhen NOT to use: This fix should not be used if maintaining backward compatibility with existing cookie handling is critical.\n\n
Why This Fix Works in Production
- Trigger: ```python-traceback
- Mechanism: Cookies with duplicate names but different domains or paths were lost when updating the cookie jar due to SimpleCookie's behavior
- If left unfixed, this can cause silent data inconsistencies that propagate (bad cache entries, incorrect downstream decisions).
Why This Breaks in Prod
- Shows up under Python 3.13.3 in real deployments (not just unit tests).
- Cookies with duplicate names but different domains or paths were lost when updating the cookie jar due to SimpleCookie's behavior
- Production symptom (often without a traceback): ```python-traceback
Proof / Evidence
- GitHub issue: #11105
- Fix PR: https://github.com/aio-libs/aiohttp/pull/11106
- Reproduced locally: No (not executed)
- Last verified: 2026-02-09
- Confidence: 0.80
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.49
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“We could wrap SimpleCookie with something like this to return all the cookies... but I don't think that is what you want. I think the…”
“I think the solution you want is to update cookie parsing to prefer Secure cookies over non-secure in HTTPS”
“the problem is we are storing cookies in SimpleCookie which doesn't support multiple cookies with the same name”
“According to RFC 6265, multiple cookies with the same name, domain, and path, the most recently received cookie overwrites the previous one in the cookie…”
Failure Signature (Search String)
- ```python-traceback
- the problem is we are storing cookies in SimpleCookie which doesn't support multiple cookies with the same name
Copy-friendly signature
Failure Signature
-----------------
```python-traceback
the problem is we are storing cookies in SimpleCookie which doesn't support multiple cookies with the same name
Error Message
Signature-only (no traceback captured)
Error Message
-------------
```python-traceback
the problem is we are storing cookies in SimpleCookie which doesn't support multiple cookies with the same name
Minimal Reproduction
"""Test script."""
import asyncio
import base64
import secrets
import orjson
from aiohttp import ClientSession
# Amazon APP info
AMAZON_APP_BUNDLE_ID = "com.amazon.echo"
AMAZON_APP_ID = "MAPiOSLib/6.0/ToHideRetailLink"
AMAZON_APP_NAME = "AioAmazonDevices"
AMAZON_APP_VERSION = "2.2.556530.0"
AMAZON_DEVICE_SOFTWARE_VERSION = "35602678"
AMAZON_DEVICE_TYPE = "A2IVLV5VM2W81"
AMAZON_CLIENT_OS = "16.6"
DEFAULT_HEADERS = {
"User-Agent": (
f"Mozilla/5.0 (iPhone; CPU iPhone OS {AMAZON_CLIENT_OS.replace('.', '_')} like Mac OS X) " # noqa: E501
"AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148"
),
"Accept-Language": "en-US",
"Accept-Encoding": "gzip",
"Connection": "keep-alive",
}
URL = "https://www.amazon.it/ap/signin"
async def main() -> None:
"""Start script."""
session = ClientSession(
headers=DEFAULT_HEADERS,
cookies=await _build_init_cookies(),
)
resp = await session.request("POST", URL)
print("Cookies:")
print(resp.cookies)
print("--------")
print("Headers:")
print(resp.headers)
async def _build_init_cookies() -> dict[str, str]:
"""Build initial cookies to prevent captcha in most cases."""
token_bytes = secrets.token_bytes(313)
frc = base64.b64encode(token_bytes).decode("ascii").rstrip("=")
map_md_dict = {
"device_user_dictionary": [],
"device_registration_data": {
"software_version": AMAZON_DEVICE_SOFTWARE_VERSION,
},
"app_identifier": {
"app_version": AMAZON_APP_VERSION,
"bundle_id": AMAZON_APP_BUNDLE_ID,
},
}
map_md_str = orjson.dumps(map_md_dict).decode("utf-8")
map_md = base64.b64encode(map_md_str.encode()).decode().rstrip("=")
return {"amzn-app-id": AMAZON_APP_ID, "frc": frc, "map-md": map_md}
if __name__ == "__main__":
asyncio.run(main())
Environment
- Python: 3.13.3
Why It Broke
Cookies with duplicate names but different domains or paths were lost when updating the cookie jar due to SimpleCookie's behavior
Fix Options (Details)
Option A — Apply the official fix
Fixes an issue where cookies with duplicate names but different domains or paths were being lost when updating the cookie jar. The root cause was that SimpleCookie uses only the cookie name as its key, causing later cookies with the same name to overwrite earlier ones.
Fix reference: https://github.com/aio-libs/aiohttp/pull/11106
Last verified: 2026-02-09. Validate in your environment.
When NOT to Use This Fix
- This fix should not be used if maintaining backward compatibility with existing cookie handling is critical.
Verify Fix
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Did This Fix Work in Your Case?
Quick signal helps us prioritize which fixes to verify and improve.
Prevention
- Capture the exact failing error string in logs and tests so you can reproduce via a minimal script.
- Pin production dependencies and upgrade only with a reproducible test that hits the failing path.
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.