shadow1ng/fscan · error

portfinger_probe_exclude_duplicate

Error message

portfinger_probe_exclude_duplicate

What it means

The probe file format allows at most one Exclude directive. parseProbesFromContent counts lines starting with "Exclude " and aborts with this error as soon as a second one is seen, because multiple exclusions cannot be represented in the current parser.

Source

Thrown at core/portfinger/probe_parser.go:194

		if lineTemp == "" || strings.HasPrefix(lineTemp, "#") {
			continue
		}
		lines = append(lines, lineTemp)
	}

	// 验证文件内容
	if len(lines) == 0 {
		return fmt.Errorf("%s", i18n.GetText("portfinger_probe_file_empty"))
	}

	// 检查Exclude指令
	excludeCount := 0
	for _, line := range lines {
		if strings.HasPrefix(line, "Exclude ") {
			excludeCount++
		}
		if excludeCount > 1 {
			return fmt.Errorf("%s", i18n.GetText("portfinger_probe_exclude_duplicate"))
		}
	}

	// 验证第一行格式
	firstLine := lines[0]
	if !strings.HasPrefix(firstLine, "Exclude ") && !strings.HasPrefix(firstLine, "Probe ") {
		return fmt.Errorf("%s", i18n.GetText("portfinger_probe_first_line_invalid"))
	}

	// 处理Exclude指令
	if excludeCount == 1 {
		v.Exclude = firstLine[len("Exclude")+1:]
		lines = lines[1:]
	}

	// 合并内容并分割探测器
	content = "\n" + strings.Join(lines, "\n")
	probeParts := strings.Split(content, "\nProbe")[1:]

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Merge the exclusion ports into a single "Exclude " line (comma-separated) and delete the duplicates.
  2. Keep only one Exclude line at the top of the probe file.
  3. Preprocess the file at load time: collect all Exclude entries and rewrite them as one line.
  4. Report the malformed file to the database maintainer if it came from upstream.

Example fix

// before
Exclude 21,25
Probe tcp GetHttp ...
Exclude 445,3306
// after
Exclude 21,25,445,3306
Probe tcp GetHttp ...
Defensive patterns

Strategy: validation

Validate before calling

func countExcludes(lines []string) int {
    n := 0
    for _, l := range lines { if strings.HasPrefix(l, "Exclude ") { n++ } }
    return n
}
// reject file if countExcludes(lines) > 1

Try / catch

if err := pf.Init(path); err != nil && strings.Contains(err.Error(), "exclude_duplicate") {
    return fmt.Errorf("merge Exclude lines into one: %w", err)
}

Prevention

When it happens

Trigger: Init/parseProbesFromContent is given a probe file containing two or more lines beginning with "Exclude ".

Common situations: Merging probe lists from multiple sources each carrying their own Exclude line, manual edits appending another Exclude, or an upstream database update that added a second Exclude.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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