shadow1ng/fscan · warning

rsync_modules_failed

Error message

rsync_modules_failed

What it means

After successfully connecting, doRsyncAuth parses the module list returned by the daemon. If getModules yields an empty list, it fails with rsync_modules_failed (ErrorTypeUnknown) because there is no module to authenticate against — rsync auth is always per-module.

Source

Thrown at plugins/services/rsync.go:123

// doRsyncAuth 执行Rsync认证
func (p *RsyncPlugin) doRsyncAuth(ctx context.Context, info *common.HostInfo, cred Credential, session *common.ScanSession) *AuthResult {
	// 先获取可用模块列表
	conn := p.connectToRsync(ctx, info, session)
	if conn == nil {
		return &AuthResult{
			Success:   false,
			ErrorType: ErrorTypeNetwork,
			Error:     fmt.Errorf("%s", i18n.GetText("rsync_connect_failed")),
		}
	}
	modules := p.getModules(conn, session.Config)
	_ = conn.Close()

	if len(modules) == 0 {
		return &AuthResult{
			Success:   false,
			ErrorType: ErrorTypeUnknown,
			Error:     fmt.Errorf("%s", i18n.GetText("rsync_modules_failed")),
		}
	}

	// 提取第一个模块名
	var firstModule string
	for _, moduleLine := range modules {
		if fields := strings.Fields(moduleLine); len(fields) > 0 {
			firstModule = fields[0]
			break
		}
	}
	if firstModule == "" {
		return &AuthResult{
			Success:   false,
			ErrorType: ErrorTypeUnknown,
			Error:     fmt.Errorf("%s", i18n.GetText("rsync_modules_failed")),
		}
	}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Enumerate modules manually: rsync rsync://<host>/ and rsync <host>:: to see what is visible.
  2. If modules are hidden (list = no), supply a known module name in the scan config instead of relying on listing.
  3. Verify with the rsyncd admin that at least one module is listable for your source IP.
  4. Check the rsync daemon protocol version compatibility.

Example fix

// before (rsyncd.conf)
[secret]
    path = /srv/data
    list = no // modules list empty -> rsync_modules_failed
// after
[secret]
    path = /srv/data
    list = yes
Defensive patterns

Strategy: validation

Validate before calling

out, _ := exec.Command("rsync", "rsync://"+host+"/").Output()
if len(strings.Fields(string(out))) == 0 {
    // no modules listed; provide explicit module name in config instead of relying on listing
}

Try / catch

if err != nil && strings.Contains(err.Error(), "rsync_modules_failed") {
    // fall back to scanning with a known module name from config
}

Prevention

When it happens

Trigger: connectToRsync succeeded and getModules ran, but the daemon returned no parsable module entries — typically every module is configured with 'list = no', or the LIST response contained only the banner and no module lines.

Common situations: Hardened rsyncd.conf hiding all modules from listing (list = no); a daemon exposing only restricted modules to the scanner IP; a non-rsync service mimicking the banner; parsing mismatch when the daemon uses an unusual rsync protocol version.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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