shadow1ng/fscan · warning

service_no_credentials

Error message

service_no_credentials

What it means

The MySQL plugin's Scan first generates the credential list via GenerateCredentials("mysql", config). If the combined config (custom credentials plus built-in defaults) yields an empty list, there is nothing to test, so Scan returns a failed ScanResult carrying the localized 'service_no_credentials' message.

Source

Thrown at plugins/services/mysql.go:54

func NewMySQLPlugin() *MySQLPlugin {
	return &MySQLPlugin{
		BasePlugin: plugins.NewBasePlugin("mysql"),
	}
}

func (p *MySQLPlugin) Scan(ctx context.Context, info *common.HostInfo, session *common.ScanSession) *ScanResult {
	config := session.Config
	state := session.State
	if config.DisableBrute {
		return p.identifyService(ctx, info, session)
	}

	credentials := GenerateCredentials("mysql", config)
	if len(credentials) == 0 {
		return &ScanResult{
			Success: false,
			Service: "mysql",
			Error:   fmt.Errorf("%s", i18n.GetText("service_no_credentials")),
		}
	}

	target := info.Target()

	// 使用公共框架进行并发凭据测试
	authFn := p.createAuthFunc(info, config, state)
	testConfig := DefaultConcurrentTestConfigWithTarget(config, info)

	result := TestCredentialsConcurrently(ctx, credentials, authFn, "mysql", testConfig)

	if result.Success {
		session.LogVuln(i18n.Tr("mysql_credential", target, result.Username, result.Password))
	}

	return result
}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Populate the credential config for mysql (usernames/passwords lists or a valid dictionary file).
  2. Check the credential file path and encoding — an empty or unreadable file yields zero credentials.
  3. Re-enable built-in default credential lists if you intended to rely on them.
  4. Log the generated credential count at startup to catch empty lists before scanning.

Example fix

// before
# config: mysql users/passwords sections empty, defaults off
// after
mysql:
  users: ["root", "admin"]
  passwords: ["123456", "password"]
Defensive patterns

Strategy: validation

Validate before calling

creds := GenerateCredentials("mysql", config)
if len(creds) == 0 {
    return fmt.Errorf("no mysql credentials configured: populate users/passwords or enable defaults")
}

Try / catch

result := plugin.Scan(ctx, info, session)
if result.Error != nil && strings.Contains(result.Error.Error(), "service_no_credentials") {
    // surface a config warning to the user instead of a scan failure
}

Prevention

When it happens

Trigger: Calling Scan with a Config whose credential sources produce zero entries — e.g. a user-supplied credential file or config section for 'mysql' that is empty, and defaults disabled via brute-force settings.

Common situations: Users pass a custom usernames/passwords file that is empty or has the wrong path/format; config disables built-in wordlists while providing no replacements; typo in the config keys so GenerateCredentials reads nothing.

Related errors


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