aio-libs/aiohttp · error · ValueError
either both host and port or none of them are allowed
Error message
either both host and port or none of them are allowed
What it means
Raised by clear_dns_cache() when exactly one of host or port is supplied. The cache is keyed by (host, port) tuples, so flushing a single host without its port (or vice versa) is ambiguous. aiohttp forces the caller to be explicit: both, to evict one entry, or neither, to wipe the cache.
Solutions
- Pass both host and port to evict a specific entry.
- Pass neither (call clear_dns_cache()) to wipe the entire cache.
- Carry host and port as a pair through your config so they are always flushed together.
- Validate that both are non-None before calling if your inputs are optional.
Example fix
# before connector.clear_dns_cache(host='example.com') # after connector.clear_dns_cache(host='example.com', port=443) # or wipe everything connector.clear_dns_cache()
Defensive patterns
Strategy: validation
Validate before calling
def clear_cache(connector, host=None, port=None):
if (host is None) != (port is None):
raise ValueError('pass both host and port, or neither')
if host is None:
connector.clear_dns_cache()
else:
connector.clear_dns_cache(host, port) Type guard
null
Try / catch
try:
connector.clear_dns_cache(host=host, port=port)
except ValueError as exc:
if 'either both' in str(exc):
connector.clear_dns_cache() # wipe entire cache as a safe fallback
else:
raise Prevention
- Carry host and port as a tuple so they are always evicted together.
- Prefer clear_dns_cache() (wipe all) when the specific port is unknown.
- Validate cache-clear inputs at the discovery layer before reaching the connector.
When it happens
Trigger: Calling connector.clear_dns_cache(host='example.com') without a port; calling clear_dns_cache(port=443) alone; looping over hosts and forgetting to pair them with ports.
Common situations: Building a tool that clears DNS for a service discovery refresh but only knows the hostname; refactoring that split host and port into separate config keys.
Related errors
- keepalive_timeout cannot be set if force_close is True
- Connector is closed
- aiohttp only supports http(s) proxies
- base_url must have a trailing '/'
- Cannot connect to unix socket
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/4a809e80a070c5d5.
Report an issue: GitHub.
Appendix: source
Thrown at aiohttp/connector.py:1118
return waiters
@property
def family(self) -> int:
"""Socket family like AF_INET."""
return self._family
@property
def use_dns_cache(self) -> bool:
"""True if local DNS caching is enabled."""
return self._use_dns_cache
def clear_dns_cache(self, host: str | None = None, port: int | None = None) -> None:
"""Remove specified host/port or clear all dns local cache."""
if host is not None and port is not None:
self._cached_hosts.remove((host, port))
elif host is not None or port is not None:
raise ValueError("either both host and port or none of them are allowed")
else:
self._cached_hosts.clear()
async def _resolve_host(
self, host: str, port: int, traces: Sequence["Trace"] | None = None
) -> list[ResolveResult]:
"""Resolve host and return list of addresses."""
if is_ip_address(host):
# Reject legacy numeric IPv4 forms (e.g. 2130706433, 127.1) that
# socket would map onto an address, slipping past a connector-level
# policy that only sees the raw host.
if ":" not in host and not is_canonical_ipv4_address(host):
raise InvalidUrlClientError(host, "is not a canonical IPv4 address")
return [
{
"hostname": host,
"host": host,
"port": port,View on GitHub (pinned to d041d4d0fd)