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.DefaultThreadNum

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Clamp or reject the offending port at config load time: keep only values in 1-65535.
  2. Fix the source data (config file, CLI flag, inventory feed) that produced the out-of-range value.
  3. If 0 means 'default port', replace it with an explicit default (e.g. 80) before building the Target.
  4. 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

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


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/7c38b05ef892a386. Report an issue: GitHub.