shadow1ng/fscan · error

fscan: invalid port

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.

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.

Appendix: 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)