shadow1ng/fscan · error

Parse error: first line must start with "Probe " or "Exclude

Error message

Parse error: first line must start with "Probe " or "Exclude "

What it means

The probe database's first meaningful line must be either an "Exclude " directive or a "Probe " directive. When lines[0] starts with anything else the parser returns this error, as the file structure cannot be interpreted from that point on. (The raw message shown is the resolution of the i18n key portfinger_probe_first_line_invalid.)

Source

Thrown at core/portfinger/probe_parser.go:201

	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:]

	// 解析每个探测器
	for _, probePart := range probeParts {
		probe := Probe{}
		if err := probe.fromString(probePart); err != nil {
			continue
		}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Make the first line of the probe file start with "Exclude " or "Probe " (exact case and trailing space).
  2. Remove any comments, headers, or junk lines above the first probe definition.
  3. If converting from nmap's probe format, rewrite lines into this parser's "Probe <proto> <name>..." grammar.
  4. Validate the file with a pre-check that asserts the first line prefix before calling Init.

Example fix

// before (probe file)
# probe database v2
Probe tcp GetHttp ...
// after
Probe tcp GetHttp ...   (no leading comment/header lines)
Defensive patterns

Strategy: validation

Validate before calling

first := firstNonEmptyLine(content)
if !strings.HasPrefix(first, "Probe ") && !strings.HasPrefix(first, "Exclude ") {
    return fmt.Errorf("probe file must start with 'Probe ' or 'Exclude '")
}

Try / catch

if err := pf.Init(path); err != nil && strings.Contains(err.Error(), "first line must start with") {
    return fmt.Errorf("probe file %s has invalid first line: %w", path, err)
}

Prevention

When it happens

Trigger: Init/parseProbesFromContent reads a probe file whose first non-empty line is neither "Exclude ..." nor "Probe ..." — e.g. a comment, blank-line artifact that wasn't skipped, header text, or a lowercase/mangled directive.

Common situations: Manually added README/comment lines at the top of the probe file, files converted from nmap-service-probes (different grammar), or corrupted downloads where the initial line was lost.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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