HumanSignal/label-studio · error · LabelStudioAPIException
Can't resolve hostname {domain}
Error message
Can't resolve hostname {domain} What it means
validate_url_for_ssrf resolves the URL's hostname via socket.gethostbyname as the first step of SSRF protection. If DNS resolution fails (socket.error), it wraps the failure in a LabelStudioAPIException: "Can't resolve hostname {domain}". This prevents proceeding to IP-based checks on an unresolvable host.
Source
Thrown at label_studio/core/utils/io.py:199
and the URL resolves to a local address.
- LabelStudioApiException if the hostname cannot be resolved
:param url: Url to be checked for validity/safety,
:param block_local_urls: Whether urls that resolve to local/private networks should be allowed.
"""
parsed_url = parse_url(url)
if parsed_url.scheme not in ('http', 'https'):
raise SsrfBlockedUrlError
domain = parsed_url.host
try:
ip = socket.gethostbyname(domain)
except socket.error:
from core.utils.exceptions import LabelStudioAPIException
raise LabelStudioAPIException(f"Can't resolve hostname {domain}")
if block_local_urls:
validate_ip(ip)
def validate_upload_url(url, block_local_urls=True):
"""Backward-compatible wrapper around validate_url_for_ssrf."""
return validate_url_for_ssrf(url, block_local_urls=block_local_urls)
def validate_ip(ip: str) -> None:
"""If settings.USE_DEFAULT_BANNED_SUBNETS is True, this function checks
if an IP is reserved for any of the reasons in
https://en.wikipedia.org/wiki/Reserved_IP_addresses
and raises an exception if so. Additionally, if settings.USER_ADDITIONAL_BANNED_SUBNETS
is set, it will also check against those subnets.
If settings.USE_DEFAULT_BANNED_SUBNETS is False, this function will only checkView on GitHub (pinned to 0b49e9b539)
Solutions
- Check the hostname in the URL for typos and confirm it resolves: run `nslookup <domain>` or `getent hosts <domain>` from the same host/container.
- Fix DNS configuration in your container/network (resolv.conf, CoreDNS, VPN to the private zone).
- If the target is an internal service, verify the service name matches the compose/k8s service DNS name.
- For S3 endpoints, confirm the endpoint URL is correct and reachable from the Label Studio container.
Example fix
// before
validate_url_for_ssrf("https://minio.internal.svc:9000/bucket") # DNS fails
// after — verify and use the reachable name
validate_url_for_ssrf("https://minio.default.svc.cluster.local:9000/bucket") Defensive patterns
Strategy: try-catch
Validate before calling
import socket
from urllib.parse import urlparse
try:
socket.gethostbyname(urlparse(url).hostname)
except socket.error:
raise ValueError(f'Cannot resolve hostname {urlparse(url).hostname}') Type guard
def hostname_resolves(url: str) -> bool:
try:
host = urlparse(url).hostname
return bool(host) and socket.gethostbyname(host) is not None
except socket.error:
return False Try / catch
try:
validate_upload_url(url, block_local_urls=True)
except LabelStudioAPIException as e:
if "Can't resolve hostname" in str(e):
return Response({'error': str(e), 'hint': 'Check DNS / hostname spelling'}, status=400)
raise Prevention
- Verify DNS works inside the container (getent hosts) before shipping.
- Use fully-qualified internal service names (.svc.cluster.local in k8s).
- Avoid hardcoding hostnames that depend on a specific VPN/network.
- Pre-resolve and cache endpoints used in validation.
When it happens
Trigger: Calling validate_url_for_ssrf (directly or via validate_upload_url, ssrf_safe_request, validate_s3_endpoint, validate_url) with a URL whose host cannot be resolved by DNS — bad hostname, no DNS in the container, offline environment, or stale internal hostname.
Common situations: S3/storage endpoints with typos in the hostname; Docker containers lacking DNS access to internal service names; hosts file entries removed; resolving private names that only exist in another network.
Related errors
- URL resolves to a reserved network address (block: {subnet})
- extract_message(e)
- Validation failed on {}: {}
- Label config contains non-unique names:
- toName="{toName}" not found in names: {sorted(names)}
AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29).
Data as JSON: /api/errors/86a43341895126f5.
Report an issue: GitHub.