{"id":"d718623b638aac29","repo":"aio-libs/aiohttp","slug":"ssl-should-be-sslcontext-fingerprint-or-bool-go-d71862","errorCode":null,"errorMessage":"ssl should be SSLContext, Fingerprint, or bool, got {ssl!r} instead.","messagePattern":"ssl should be SSLContext, Fingerprint, or bool, got (.+?) instead\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"aiohttp/connector.py","lineNumber":1025,"sourceCode":"        limit_per_host: int = 0,\n        enable_cleanup_closed: bool = False,\n        timeout_ceil_threshold: float = 5,\n        happy_eyeballs_delay: float | None = 0.25,\n        interleave: int | None = None,\n        socket_factory: SocketFactoryType | None = None,\n        ssl_shutdown_timeout: _SENTINEL | None | float = sentinel,\n    ):\n        super().__init__(\n            keepalive_timeout=keepalive_timeout,\n            force_close=force_close,\n            limit=limit,\n            limit_per_host=limit_per_host,\n            enable_cleanup_closed=enable_cleanup_closed,\n            timeout_ceil_threshold=timeout_ceil_threshold,\n        )\n\n        if not isinstance(ssl, SSL_ALLOWED_TYPES):\n            raise TypeError(\n                \"ssl should be SSLContext, Fingerprint, or bool, \"\n                f\"got {ssl!r} instead.\"\n            )\n        self._ssl = ssl\n\n        self._resolver: AbstractResolver\n        if resolver is None:\n            self._resolver = DefaultResolver()\n            self._resolver_owner = True\n        else:\n            self._resolver = resolver\n            self._resolver_owner = False\n\n        self._use_dns_cache = use_dns_cache\n        self._cached_hosts = _DNSCacheTable(\n            ttl=ttl_dns_cache, max_size=dns_cache_max_size\n        )\n        self._throttle_dns_futures: dict[tuple[str, int], set[asyncio.Future[None]]] = (","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/connector.py#L1007-L1043","documentation":"Raised by TCPConnector.__init__ when the `ssl` argument is not one of SSLContext, Fingerprint, or bool (the tuple SSL_ALLOWED_TYPES). aiohttp checks at construction so that an invalid ssl policy fails fast rather than producing confusing handshake errors later. Note: on builds compiled without ssl, only bool is allowed.","triggerScenarios":"Passing `TCPConnector(ssl='true')`, `ssl=1` (int, not bool), `ssl=None` to TCPConnector (None is not in the allowed tuple), or `ssl={'verify': False}`.","commonSituations":"String 'true'/'false' from an env var passed verbatim. Integer 0/1 instead of bool. Confusing `verify_ssl`/`fingerprint` kwargs (which go on the request) with the connector-level `ssl`. Passing None expecting 'use defaults' (use True or an SSLContext instead).","solutions":["Pass a bool: `TCPConnector(ssl=False)` to disable verification, `ssl=True` to use a verified default context.","Pass an `ssl.SSLContext` you configured, or an `aiohttp.Fingerprint` for pinning.","Coerce env-var strings: `ssl=(os.environ['VERIFY'] == 'true')` rather than passing the string."],"exampleFix":"# before\nconnector = aiohttp.TCPConnector(ssl='false')\n# after\nconnector = aiohttp.TCPConnector(ssl=False)","handlingStrategy":"type-guard","validationCode":"import ssl\nfrom aiohttp import Fingerprint\n\ndef coerce_ssl(v):\n    if isinstance(v, (ssl.SSLContext, Fingerprint, bool)):\n        return v\n    if isinstance(v, int):\n        return bool(v)\n    if isinstance(v, str):\n        return v.lower() == 'true'\n    raise TypeError(f'invalid ssl value: {v!r}')","typeGuard":"import ssl\nfrom aiohttp import Fingerprint\n\ndef is_valid_ssl(v) -> bool:\n    return isinstance(v, (ssl.SSLContext, Fingerprint, bool))","tryCatchPattern":"try:\n    connector = aiohttp.TCPConnector(ssl=ssl_value)\nexcept TypeError as e:\n    if 'ssl should be' in str(e):\n        connector = aiohttp.TCPConnector(ssl=coerce_ssl(ssl_value))\n    raise","preventionTips":["Always coerce env-var-sourced ssl to bool at the config boundary.","Keep an SSLContext (or True/False) as the canonical representation in your config dataclass.","Unit-test the connector factory with all expected ssl input shapes."],"tags":["connector","ssl","type-validation","config"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}