shadow1ng/fscan · error

auth function is nil

Error message

auth function is nil

What it means

TestSingleCredential was invoked with a nil authFn — the function responsible for performing an auth attempt against a target. Since no test can run, it returns an AuthResult with Success:false, ErrorTypeUnknown, and the 'auth function is nil' error. This is a programming/configuration bug, not a network outcome.

Source

Thrown at plugins/services/credential_tester.go:86

func authCleanupWait() time.Duration {
	return time.Duration(atomic.LoadInt64(&authCleanupWaitNanos))
}

// =============================================================================
// 单凭据测试(解决 goroutine 泄漏)
// =============================================================================

// TestSingleCredential 安全地测试单个凭据
// 正确处理 context 取消时的资源清理
func TestSingleCredential(ctx context.Context, cred Credential, authFn AuthFunc) *AuthResult {
	if ctx == nil {
		ctx = context.Background()
	}
	if authFn == nil {
		return &AuthResult{
			Success:   false,
			ErrorType: ErrorTypeUnknown,
			Error:     fmt.Errorf("auth function is nil"),
		}
	}
	if err := ctx.Err(); err != nil {
		return &AuthResult{
			Success:   false,
			ErrorType: ErrorTypeNetwork,
			Error:     err,
		}
	}

	resultChan := make(chan *AuthResult, 1)

	go func() {
		defer func() {
			if r := recover(); r != nil {
				resultChan <- &AuthResult{
					Success:   false,
					ErrorType: ErrorTypeUnknown,

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Fix the caller to construct and pass a non-nil authFn (e.g. p.createAuthFunc(info, config, state)) before invoking TestSingleCredential.
  2. Add an early check in the calling plugin so nil authFn is caught and reported with plugin context.
  3. In tests, this is expected behavior — assert on ErrorTypeUnknown and the message rather than treating it as a scan failure.

Example fix

// before
result := TestSingleCredential(ctx, target, cred, nil, state)
// after
authFn := p.createAuthFunc(info, config, state)
result := TestSingleCredential(ctx, target, cred, authFn, state)
Defensive patterns

Strategy: validation

Validate before calling

if authFn == nil {
    return fmt.Errorf("plugin %s produced nil auth function; check createAuthFunc wiring", pluginName)
}
result := TestSingleCredential(ctx, target, cred, authFn, state)

Try / catch

res := TestSingleCredential(ctx, target, cred, authFn, state)
if !res.Success && res.ErrorType == ErrorTypeUnknown && res.Error.Error() == "auth function is nil" {
    log.Printf("tester misconfigured: authFn missing for %s", target)
}

Prevention

When it happens

Trigger: testCredentialWithRetry (or tests) calls TestSingleCredential without supplying an authFn, e.g. a plugin forgot to build its auth function via createAuthFunc or passed an uninitialized function variable.

Common situations: Plugin registration code that constructs the tester before wiring authFn; refactor left authFn unassigned; a nil return from createAuthFunc on a misconfigured plugin passed straight through.

Related errors


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