shadow1ng/fscan · error · ErrInvalidURL
%w: invalid port (ErrInvalidURL)
Error message
%w: invalid port (ErrInvalidURL)
What it means
buildTargetURL detects a structurally malformed port when the URL carries no explicit port but its host part embeds one in an unparseable form (via hasMalformedWebURLPort). It returns ErrInvalidURL so callers can distinguish bad input from transport failures.
Source
Thrown at webscan/web_scan.go:120
protocol = protocolHTTPS
}
info.URL = protocol + net.JoinHostPort(info.Host, fmt.Sprint(info.Port))
} else if !hasProtocolPrefix(info.URL) {
info.URL = protocolHTTP + normalizeSchemelessWebTarget(info.URL)
}
// 解析URL以提取基础部分
parsedURL, err := url.Parse(info.URL)
if err != nil {
return "", fmt.Errorf("%w: %w", ErrInvalidURL, err)
}
if parsedURL.Hostname() == "" {
return "", fmt.Errorf("%w: empty host", ErrInvalidURL)
}
portStr := parsedURL.Port()
if portStr == "" {
if hasMalformedWebURLPort(parsedURL.Host) {
return "", fmt.Errorf("%w: invalid port", ErrInvalidURL)
}
} else {
port, err := strconv.Atoi(portStr)
if err != nil || port < 1 || port > 65535 {
return "", fmt.Errorf("%w: invalid port %q", ErrInvalidURL, portStr)
}
}
parsedURL.Host = normalizeWebURLHost(parsedURL.Host)
return fmt.Sprintf("%s://%s", parsedURL.Scheme, parsedURL.Host), nil
}
// hasProtocolPrefix 检查URL是否包含协议前缀
func hasProtocolPrefix(urlStr string) bool {
urlStr = strings.ToLower(urlStr)
return strings.HasPrefix(urlStr, protocolHTTP) || strings.HasPrefix(urlStr, protocolHTTPS)
}
View on GitHub (pinned to 95cc12e753)
Solutions
- Fix the target URL so the port is either absent or a valid decimal (1-65535), e.g. http://example.com:8080
- Check template/placeholder substitution produced a real port value
- Validate ports with strconv.Atoi and range check before submitting the target
Example fix
// before
url := fmt.Sprintf("http://%s:%s", host, port) // port may be empty
// after
if port != "" {
n, err := strconv.Atoi(port)
if err != nil || n < 1 || n > 65535 {
return fmt.Errorf("invalid port %q", port)
}
}
url := fmt.Sprintf("http://%s", net.JoinHostPort(host, port)) Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(target)
if err != nil || (u.Port() == "" && strings.Contains(u.Host, ":")) {
return fmt.Errorf("target %q has malformed port", target)
} Try / catch
if err := WebScan(target); errors.Is(err, ErrInvalidURL) {
log.Printf("invalid target URL %q: %v", target, err)
return nil
} Prevention
- Use net.JoinHostPort(host, port) instead of Sprintf concatenation
- Verify template placeholders for ports are substituted
- Reject URLs with trailing colons in input validation
When it happens
Trigger: URLs like "http://example.com:/path" or hosts such as "example.com:port" where url.Parse yields an empty Port() but the raw Host contains a colon segment that is not a valid decimal port.
Common situations: Template string bugs like fmt.Sprintf("http://%s:%s", host, portVar) with empty/placeholder port, copy-paste of URLs with a trailing colon, or port placeholders like :<port> left unsubstituted.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- %w: empty host (ErrInvalidURL)
- %w: invalid port %q (ErrInvalidURL)
- result cannot be nil
- result cannot be nil
- output file not specified
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/fdbc9d6470f6cf7f.
Report an issue: GitHub.