shadow1ng/fscan · warning

service_not_identified

Error message

service_not_identified

What it means

identifyService probes the target and tries to classify the response banner as MSSQL by looking for markers such as 'sql server' in the response/error text. When the banner cannot be identified as MSSQL, it returns a failed ScanResult with i18n message 'service_not_identified' parameterized with 'MSSQL'.

Source

Thrown at plugins/services/mssql.go:158

		state.IncrementTCPSuccessPacketCount()
	}

	var banner string
	errLower := ""
	if err != nil {
		errLower = strings.ToLower(err.Error())
	}

	if err == nil || (result != nil && result.isMSSQL()) ||
		(strings.Contains(errLower, "login failed") ||
			strings.Contains(errLower, "mssql") ||
			strings.Contains(errLower, "sql server")) {
		banner = "MSSQL"
	} else {
		return &ScanResult{
			Success: false,
			Service: "mssql",
			Error:   fmt.Errorf("%s", i18n.Tr("service_not_identified", "MSSQL")),
		}
	}

	session.LogSuccess(i18n.Tr("mssql_service", target, banner))

	return &ScanResult{
		Type:    plugins.ResultTypeService,
		Success: true,
		Service: "mssql",
		Banner:  banner,
	}
}

func init() {
	RegisterPluginWithPorts("mssql", func() Plugin {
		return NewMSSQLPlugin()
	}, []int{1433, 1434})
}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Verify the target port actually runs MSSQL/TDS (1433 or configured port)
  2. Widen the banner match to include more SQL Server error markers or use a TDS prelogin probe
  3. Bypass identification by forcing the mssql plugin if the service is known
  4. Inspect the raw probe response to add the missing banner keyword to the match list

Example fix

// before
} else {
    return &ScanResult{Success: false, Error: fmt.Errorf("%s", i18n.Tr("service_not_identified", "MSSQL"))}
}
// after
} else if strings.Contains(errLower, "microsoft") || strings.Contains(errLower, "tds") {
    banner = "MSSQL"
} else {
    return &ScanResult{Success: false, Error: fmt.Errorf("%s", i18n.Tr("service_not_identified", "MSSQL"))}
}
Defensive patterns

Strategy: fallback

Validate before calling

// confirm the service before running MSSQL identification
conn, err := net.DialTimeout("tcp", target, 5*time.Second)
if err != nil { return err }
// send a TDS prelogin and check the response mentions SQL Server
banner, err := probeTDSBanner(conn)
if err != nil || !strings.Contains(strings.ToLower(banner), "sql server") {
    return errors.New("target does not look like MSSQL; skipping plugin")
}

Try / catch

res := plugin.Scan(info, config, state)
if !res.Success && res.Error != nil && strings.Contains(res.Error.Error(), "service_not_identified") {
    // fall back to a generic port/service scan to classify the target
    log.Printf("service not identified as MSSQL: %v", res.Error)
}

Prevention

When it happens

Trigger: Scan → identifyService: the probe response (or its error text) contains none of the expected markers (e.g. 'sql server'), so the else-branch fires. Typical with non-MSSQL services on port 1433, TLS-wrapped TDS banners, or locally translated/obscure server error text.

Common situations: Scanning a MySQL/PostgreSQL port mislabeled as 1433; SQL Server configured to hide its version; proxy or VPN altering the banner; a case variant not matched by strings.Contains on errLower.

Related errors


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