{"record":{"id":"b49a47e3d62344df","repo":"Freika/dawarich","slug":"could-not-resolve-hostname-host","errorCode":null,"errorMessage":"Could not resolve hostname: %{host}","messagePattern":"Could not resolve hostname: %(.+?)","errorType":"validation","errorClass":"UrlValidatable::BlockedUrlError","httpStatus":null,"severity":"warning","filePath":"app/services/concerns/url_validatable.rb","lineNumber":82,"sourceCode":"      raise BlockedUrlError, I18n.t('services.concerns.url_validatable.invalid_scheme', scheme: uri.scheme)\n    end\n    raise BlockedUrlError, I18n.t('services.concerns.url_validatable.host_required') if uri.host.blank?\n\n    # Cloud refuses URLs that embed credentials. Self-hosters legitimately\n    # use http://user:pass@host — homelab Immich behind nginx basic-auth\n    # is a real config we don't want to break.\n    if uri.userinfo.present? && !DawarichSettings.self_hosted?\n      raise BlockedUrlError, I18n.t('services.concerns.url_validatable.embedded_credentials')\n    end\n\n    ip = IPAddr.new(Resolv.getaddress(uri.host))\n    if blocked_ranges.any? { |range| range.include?(ip) }\n      raise BlockedUrlError, I18n.t('services.concerns.url_validatable.blocked_address')\n    end\n  rescue URI::InvalidURIError\n    raise BlockedUrlError, I18n.t('services.concerns.url_validatable.invalid_format')\n  rescue Resolv::ResolvError\n    raise BlockedUrlError, I18n.t('services.concerns.url_validatable.unresolvable_host', host: uri.host)\n  end\n\n  def blocked_ranges\n    if DawarichSettings.self_hosted?\n      ALWAYS_BLOCKED_RANGES\n    else\n      ALWAYS_BLOCKED_RANGES + CLOUD_ONLY_BLOCKED_RANGES\n    end\n  end\nend\n","sourceCodeStart":64,"sourceCodeEnd":93,"githubUrl":"https://github.com/Freika/dawarich/blob/97fad417c5a11b0eb11157890635e015723a2e97/app/services/concerns/url_validatable.rb#L64-L93","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nurl = 'http://immich.local:2283' # mDNS, Resolv raises -> BlockedUrlError\n\n# after (container that can reach the host)\nurl = 'http://immich.lan.example.com:2283' # resolvable via LAN DNS configured in compose:\n# services:\n#   web:\n#     dns: [192.168.1.1]","handlingStrategy":"validation","validationCode":"Resolv.getaddress(URI.parse(url).host) # raises Resolv::ResolvError if unresolvable - pre-flight check","typeGuard":"def resolvable_url?(s)\n  u = URI.parse(s.to_s)\n  return false unless u.host\n  Resolv.getaddress(u.host)\n  true\nrescue StandardError\n  false\nend","tryCatchPattern":"begin\n  validate_integration_url!(url)\nrescue BlockedUrlError => e\n  errors.add(:url, \"Hostname does not resolve from this server\")\nend","preventionTips":["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."],"tags":["url-validation","dns","network","integrations","ruby"],"backgroundTag":"dns-resolution-failed","analyzedSha":"97fad417c5a11b0eb11157890635e015723a2e97","analyzedAt":"2026-08-21T17:04:17.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}