aio-libs/aiohttp · error · ValueError
Domain cannot be empty
Error message
Domain cannot be empty
What it means
Raised as ValueError by Domain.validation when, after stripping trailing dots and lowercasing, the domain string is empty. A host rule with no hostname cannot match anything meaningful, so it is rejected. Triggered via Domain(''), Domain('.'), or Domain(' ') after normalization.
Source
Thrown at aiohttp/web_urldispatcher.py:784
class Domain(AbstractRuleMatching):
re_part = re.compile(r"(?!-)[a-z\d-]{1,63}(?<!-)")
def __init__(self, domain: str) -> None:
super().__init__()
self._domain = self.validation(domain)
@property
def canonical(self) -> str:
return self._domain
def validation(self, domain: str) -> str:
if not isinstance(domain, str):
raise TypeError("Domain must be str")
domain = domain.rstrip(".").lower()
if not domain:
raise ValueError("Domain cannot be empty")
elif "://" in domain:
raise ValueError("Scheme not supported")
url = URL("http://" + domain)
assert url.raw_host is not None
if not all(self.re_part.fullmatch(x) for x in url.raw_host.split(".")):
raise ValueError("Domain not valid")
if url.port == 80:
return url.raw_host
return f"{url.raw_host}:{url.port}"
async def match(self, request: Request) -> bool:
host = request.headers.get(hdrs.HOST)
if not host:
return False
return self.match_domain(host)
def match_domain(self, host: str) -> bool:
return host.lower() == self._domainView on GitHub (pinned to c0ef574e29)
Solutions
- Provide a real hostname: Domain('example.com').
- Filter empty values from config lists before constructing Domain rules.
- Guard config with: if host: app.add_domain(host, sub_app).
Example fix
# before
host = os.environ.get('HOST', '')
app.add_domain(host, sub_app) # '' raises
# after
host = os.environ.get('HOST', '')
if host:
app.add_domain(host, sub_app) Defensive patterns
Strategy: validation
Validate before calling
def clean_domain(domain: str) -> str:
d = domain.strip().rstrip('.').lower()
if not d:
raise ValueError('Domain cannot be empty')
return d Type guard
def is_nonempty_domain(domain) -> bool:
return isinstance(domain, str) and bool(domain.strip().rstrip('.')) Try / catch
try:
app.add_domain(host, sub_app)
except ValueError as e:
if 'empty' in str(e):
log.warning('skipping empty host rule')
else:
raise Prevention
- Filter empty/whitespace entries from host config lists.
- Guard add_domain calls with 'if host:' checks.
- Validate domain rules in config-loading tests.
When it happens
Trigger: Constructing aiohttp.web.Domain('') or Domain('.'), or app.add_domain('', sub_app). Also when a host variable from config is an empty string or only whitespace/ dots.
Common situations: Empty host config value; environment variable unset (defaulting to ''); building domain rules from a list that contained an empty element.
Related errors
- Scheme not supported
- '{directory}' is not a directory
- Domain must be str
- base_url must have a trailing '/'
- {url}
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/465f3b65fdedbbc8.json.
Report an issue: GitHub.