Freika/dawarich · warning · UrlValidatable::BlockedUrlError
Could not resolve hostname: %{host}
Error message
Could not resolve hostname: %{host} What it means
Raised as BlockedUrlError when Resolv.getaddress raises Resolv::ResolvError during DNS lookup of the URL's host — the hostname cannot be resolved to any IP address. The validator resolves the host to run its SSRF range check, so an unresolvable name stops the flow with the offending host included in the message.
Source
Thrown at app/services/concerns/url_validatable.rb:82
raise BlockedUrlError, I18n.t('services.concerns.url_validatable.invalid_scheme', scheme: uri.scheme)
end
raise BlockedUrlError, I18n.t('services.concerns.url_validatable.host_required') if uri.host.blank?
# Cloud refuses URLs that embed credentials. Self-hosters legitimately
# use http://user:pass@host — homelab Immich behind nginx basic-auth
# is a real config we don't want to break.
if uri.userinfo.present? && !DawarichSettings.self_hosted?
raise BlockedUrlError, I18n.t('services.concerns.url_validatable.embedded_credentials')
end
ip = IPAddr.new(Resolv.getaddress(uri.host))
if blocked_ranges.any? { |range| range.include?(ip) }
raise BlockedUrlError, I18n.t('services.concerns.url_validatable.blocked_address')
end
rescue URI::InvalidURIError
raise BlockedUrlError, I18n.t('services.concerns.url_validatable.invalid_format')
rescue Resolv::ResolvError
raise BlockedUrlError, I18n.t('services.concerns.url_validatable.unresolvable_host', host: uri.host)
end
def blocked_ranges
if DawarichSettings.self_hosted?
ALWAYS_BLOCKED_RANGES
else
ALWAYS_BLOCKED_RANGES + CLOUD_ONLY_BLOCKED_RANGES
end
end
end
View on GitHub (pinned to 97fad417c5)
Solutions
- From the server (or its container) run: getent hosts <host> / Resolv.getaddress('<host>') to confirm the name resolves in the app's network context, not just your laptop.
- Fix the hostname typo, or use an IP literal / publicly resolvable name.
- For Docker self-hosting, ensure the container uses a DNS server that can resolve your internal names (docker --dns, compose dns: block).
- If DNS is merely young, wait for propagation and retry the save.
Example fix
# before url = 'http://immich.local:2283' # mDNS, Resolv raises -> BlockedUrlError # after (container that can reach the host) url = 'http://immich.lan.example.com:2283' # resolvable via LAN DNS configured in compose: # services: # web: # dns: [192.168.1.1]
Defensive patterns
Strategy: validation
Validate before calling
Resolv.getaddress(URI.parse(url).host) # raises Resolv::ResolvError if unresolvable - pre-flight check
Type guard
def resolvable_url?(s) u = URI.parse(s.to_s) return false unless u.host Resolv.getaddress(u.host) true rescue StandardError false end
Try / catch
begin validate_integration_url!(url) rescue BlockedUrlError => e errors.add(:url, "Hostname does not resolve from this server") end
Prevention
- Remember the resolving party is the server container, not the user's browser — test DNS from there.
- Avoid mDNS '.local' names in server-side integrations; use real DNS or IPs.
- Configure container DNS (compose dns:) when internal names must resolve.
When it happens
Trigger: Typos in the hostname ('immich.exmaple.com'), hosts that exist only on the user's LAN with no public DNS record, DNS outages or broken resolv.conf in the container running the app, freshly-created DNS records that have not propagated, or '.local' mDNS names which standard DNS resolvers cannot answer.
Common situations: Self-hosted Docker deployments where the app container lacks access to the LAN DNS that would resolve homelab names, users entering mDNS names like 'immich.local', DNS entries created seconds before, restrictive cloud egress DNS policies, IPv6-only hosts with broken A/AAAA resolution.
Understand the failure class
- DNS resolution errors: ENOTFOUND and getaddrinfo failures — how hostname lookups fail and how to debug them.
Related errors
- URL resolves to a blocked address
- Invalid URL scheme: %{scheme}
- URL must include a host
- URL must not embed credentials (user:pass@host)
- Invalid URL format
AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21).
Data as JSON: /api/errors/b49a47e3d62344df.
Report an issue: GitHub.