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
- 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
- Validate the range with IPAddr before passing it to WhatWeb (rescue IPAddr::InvalidAddressError yourself)
- Use CIDR notation instead when possible (192.168.1.0/24), which avoids the range parser
- 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
- Use strict dotted-quad ranges with a single dash and no spaces
- Prefer CIDR notation (a.b.c.d/nn) to avoid the range parser entirely
- Sanitize targets read from files: strip whitespace and reject blanks
- Pre-validate with IPAddr.new before invoking WhatWeb
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
- You must specify the available versions of the product
- You must specify the available url of the website
- No target
- Unable to parse invalid target. No hostname.
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)