urbanadventurer/WhatWeb · error

Error parsing target IP range: #

Error message

Error parsing target IP range: #{e}

What it means

When WhatWeb parses a target string that looks like an IP range (e.g. 192.168.1.1-192.168.1.254), make_target_list converts the endpoints with IPAddr. Any exception raised during this parsing (malformed IP text, reversed/invalid ranges) is re-raised as 'Error parsing target IP range: <original error>'. The original exception message is embedded, so read it for the root cause.

Solutions

  1. Read the embedded inner error and correct the offending range string to strict dotted-quad form, e.g. 192.168.1.1-192.168.1.254
  2. Validate the range with IPAddr before passing it to WhatWeb (rescue IPAddr::InvalidAddressError yourself)
  3. Use CIDR notation instead when possible (192.168.1.0/24), which avoids the range parser
  4. Split comma-separated targets and check each individually to isolate the bad one

Example fix

// before
whatweb 192.168.1.1-192.168.1..254
// after
whatweb 192.168.1.1-192.168.1.254
Defensive patterns

Strategy: validation

Validate before calling

require 'ipaddr'
def valid_ip_range?(s)
  m = s.match(/\A([\d.]+)-([\d.]+)\z/)
  return false unless m
  IPAddr.new(m[1], Socket::AF_INET)
  IPAddr.new(m[2], Socket::AF_INET)
  true
rescue IPAddr::InvalidAddressError
  false
end

Type guard

def dotted_quad?(s)
  /\A(\d{1,3}\.){3}\d{1,3}\z/.match?(s)
end

Try / catch

begin
  WhatWeb::Scanner.new([range_target])
rescue RuntimeError => e
  raise unless e.message.start_with?('Error parsing target IP range:')
  warn "Fix range syntax: #{e.message}"
end

Prevention

When it happens

Trigger: Passing a malformed IP range on the command line or in the target list: non-numeric octets (192.168.1.x-192.168.1.20), extra characters, IPv6 text matched by the IPv4 regex, or an end IP smaller than start IP in downstream logic.

Common situations: Typoed CIDR/range syntax by the operator (dash vs colon, stray spaces); copy-pasted ranges with whitespace or trailing characters; scripts interpolating unvalidated host ranges into the target argument.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at lib/whatweb/scan.rb:229

        if x =~ %r{^[0-9\.\-\/]+$} && x !~ %r{^[\d\.]+$}
          begin
            # CIDR notation
            if x =~ %r{\d+\.\d+\.\d+\.\d+/\d+$}
              range = IPAddr.new(x).to_range.map(&:to_s)
            # x.x.x.x-x
            elsif x =~ %r{^(\d+\.\d+\.\d+\.\d+)-(\d+)$}
              start_ip = IPAddr.new(Regexp.last_match(1), Socket::AF_INET)
              end_ip   = IPAddr.new("#{start_ip.to_s.split('.')[0..2].join('.')}.#{Regexp.last_match(2)}", Socket::AF_INET)
              range = (start_ip..end_ip).map(&:to_s)
            # x.x.x.x-x.x.x.x
            elsif x =~ %r{^(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)$}
              start_ip = IPAddr.new(Regexp.last_match(1), Socket::AF_INET)
              end_ip   = IPAddr.new(Regexp.last_match(2), Socket::AF_INET)
              range = (start_ip..end_ip).map(&:to_s)
            end
          rescue => e
            # Something went horribly wrong parsing the target IP range
            raise "Error parsing target IP range: #{e}"
          end
        end
        range
      end.compact.flatten

      # TODO: refactor this. data which matches these regexs should be taken care of above
      url_list = url_list.select { |x| !(x =~ %r{^[0-9\.\-*\/]+$}) || x =~ /^[\d\.]+$/ }
      url_list += ip_range unless ip_range.empty?

      # make urls friendlier, test if it's a file, if test for not assume it's http://
      # http, https, ftp, etc
      push_to_urllist = []
      consecutive_errors = 0
      inputfile_name = opts[:input_file] # Store for error messages
      
      # TODO: refactor this
      url_list = url_list.map do |x|
        if File.exist?(x)

View on GitHub (pinned to d279d93042)