urbanadventurer/WhatWeb · error

Unable to parse invalid target. No hostname.

Error message

Unable to parse invalid target. No hostname.

What it means

make_target_list validates each target string by parsing it with Addressable::URI. If parsing succeeds but the resulting URI has an empty host (no hostname), WhatWeb raises 'Unable to parse invalid target. No hostname.' because it cannot resolve or connect to a target without a host.

Solutions

  1. Supply a full target with a hostname, e.g. http://example.com/ or example.com
  2. Pre-validate each target: Addressable::URI.parse(x) and check !domain.host.to_s.empty? before running
  3. Trim and skip empty/blank lines when reading targets from a file (x.split(/\s+/).reject(&:empty?))
  4. If the target was meant to be a local file or IP range, use the appropriate input form rather than a bare path string

Example fix

// before
whatweb /admin/login.php
// after
whatweb http://example.com/admin/login.php
Defensive patterns

Strategy: validation

Validate before calling

require 'addressable/uri'
def has_hostname?(s)
  uri = Addressable::URI.parse(s.to_s)
  !uri.host.to_s.empty?
rescue Addressable::URI::InvalidURIError
  false
end

Type guard

def valid_target?(s)
  s.is_a?(String) && !s.strip.empty? && has_hostname?(s)
end

Try / catch

begin
  WhatWeb::Scanner.new(targets)
rescue RuntimeError => e
  raise unless e.message.include?('Unable to parse invalid target')
  warn 'Every target needs a hostname, e.g. http://example.com'
end

Prevention

When it happens

Trigger: Passing a bare string without a host — e.g. '/path/only', 'http://', a stray filename or option value — into the target list so Addressable::URI.parse yields a URI with domain.host == '' or nil-adjacent emptiness.

Common situations: Operators forgetting the scheme+host (passing just a path); shell scripts passing empty strings from unset variables; target lists with blank lines or filenames accidentally included; ambiguity where the target regex matched a non-host string like an IP range fragment.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of urbanadventurer/WhatWeb@d279d93042 (2026-09-15). Data as JSON: /api/errors/8791c69a58a444f4. Report an issue: GitHub.

Appendix: source

Thrown at lib/whatweb/scan.rb:281

              original_hostname = x.dup
              # Add HTTPS version
              https_version = "https://#{x}" 
              push_to_urllist << https_version
              # add HTTP prefix to current target
              x.sub!(/^/, 'http://')
              # Provide informational message to user
              debug("Simple hostname detected: #{original_hostname}. Testing both HTTP and HTTPS.")
            else
              # For more complex paths, just use HTTP prefix as before
              x.sub!(/^/, 'http://')
            end
          end

          # is it a valid domain?
          begin
            domain = Addressable::URI.parse(x)
            # check validity
            raise 'Unable to parse invalid target. No hostname.' if domain.host.empty?

            # convert IDN domain
            x = domain.normalize.to_s if domain.host !~ %r{^[a-zA-Z0-9\.:/]*$}
            
            # Reset counter on successful parse
            consecutive_errors = 0
          rescue => e
            # Count consecutive errors
            consecutive_errors += 1
            
            # Abort after 10 consecutive parsing errors
            if consecutive_errors >= 10
              error("Aborting target processing after #{consecutive_errors} consecutive parsing errors.")
              error("The input appears to contain invalid URLs or non-URL data.")
              error("Please check your input and ensure it contains valid URLs.")
              break
            end
            

View on GitHub (pinned to d279d93042)