shadow1ng/fscan · error
fscan: invalid port %d
Error message
fscan: invalid port %d
What it means
This is the per-target port validation branch of validateConfig: every port in Target.Ports must be an integer between 1 and 65535. A port outside that range is not a valid TCP port, so the library refuses to build the fscan flag variables and returns this error before scanning.
Source
Thrown at pkg/fscan/scanner.go:354
}
for _, name := range normalizePlugins(config.Plugins) {
if !plugins.Exists(name) {
return fmt.Errorf("fscan: plugin %q not found", name)
}
if !config.AllowUnsafePlugins && !IsSafePlugin(name) {
return fmt.Errorf("fscan: plugin %q is not enabled for embedded safe mode", name)
}
}
for _, target := range targets {
if strings.TrimSpace(target.Host) == "" && strings.TrimSpace(target.URL) == "" {
return fmt.Errorf("fscan: target host or URL is required")
}
if strings.TrimSpace(target.Host) != "" && strings.TrimSpace(target.URL) != "" {
return fmt.Errorf("fscan: target cannot set both Host and URL")
}
for _, port := range target.Ports {
if port < 1 || port > 65535 {
return fmt.Errorf("fscan: invalid port %d", port)
}
}
}
for _, port := range config.Ports {
if port < 1 || port > 65535 {
return fmt.Errorf("fscan: invalid port %d", port)
}
}
return nil
}
func buildFlagVars(config Config, target Target) *common.FlagVars {
timeout := secondsOrDefault(config.Timeout, common.DefaultTimeout)
webTimeout := secondsOrDefault(config.WebTimeout, 5)
threadNum := config.Threads
if threadNum <= 0 {
threadNum = common.DefaultThreadNumView on GitHub (pinned to 95cc12e753)
Solutions
- Clamp or reject the offending port at config load time: keep only values in 1-65535.
- Fix the source data (config file, CLI flag, inventory feed) that produced the out-of-range value.
- If 0 means 'default port', replace it with an explicit default (e.g. 80) before building the Target.
- Validate the whole Targets slice with your own loop before calling ValidateConfig to get a better error message.
Example fix
// before
target.Ports = []int{80, 0, 8080}
// after
for _, p := range rawPorts {
if p >= 1 && p <= 65535 {
target.Ports = append(target.Ports, p)
}
} Defensive patterns
Strategy: validation
Validate before calling
func validPorts(ps []int) bool {
for _, p := range ps {
if p < 1 || p > 65535 { return false }
}
return true
} Type guard
func isValidPort(p int) bool { return p >= 1 && p <= 65535 } Try / catch
if err := fscan.ValidateConfig(cfg); err != nil {
var perr *strconv.NumError // if ports parsed from strings
if strings.Contains(err.Error(), "invalid port") {
log.Printf("bad port in target config: %v", err)
}
return err
} Prevention
- Parse port strings with strconv.Atoi and range-check immediately.
- Never use 0 as a placeholder port; omit the entry instead.
- Centralize port parsing in one validated helper.
When it happens
Trigger: A Target in config.Targets has a Ports entry of 0, negative, or > 65535 when ValidateConfig or scanEach runs.
Common situations: Zero-value int used as a placeholder port; parsing port strings like '70000' or '-1' from CLI/config without range checks; accidental off-by-one where a count (e.g. 65536) was stored instead of the max port.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- result cannot be nil
- result cannot be nil
- output file not specified
- invalid output format: %s
- parser_cidr_failed: %w
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/7c38b05ef892a386.
Report an issue: GitHub.