projectdiscovery/nuclei · error
waiting for login/username prompt: %w
Error message
waiting for login/username prompt: %w
What it means
Client.Auth (telnet.go:208) drives a minimal login dialog: it first waits for any of the configured UserPrompts via readUntil. Timeout (context deadline → net.Error timeout → context.DeadlineExceeded) or a read error returns 'waiting for login/username prompt: %w'. Note readUntil enforces the ctx deadline and compares lowercased needles, but only the prompts in c.UserPrompts are recognized.
Source
Thrown at pkg/utils/telnetmini/telnet.go:211
}
}
} else {
i += 2 // Skip command and option
}
}
}
return supportsEncryption, options
}
// Auth performs a minimal Telnet username/password interaction.
// It waits for a username/login prompt, sends username, waits for a password prompt,
// sends password, and then looks for fail banners or shell prompts.
// A timeout should be enforced via ctx.
func (c *Client) Auth(ctx context.Context, username, password string) error {
// Wait for username/login prompt
if _, _, err := c.readUntil(ctx, c.UserPrompts...); err != nil {
return fmt.Errorf("waiting for login/username prompt: %w", err)
}
if err := c.writeLine(ctx, username); err != nil {
return fmt.Errorf("sending username: %w", err)
}
// Wait for password prompt
if _, _, err := c.readUntil(ctx, c.PasswordPrompts...); err != nil {
return fmt.Errorf("waiting for password prompt: %w", err)
}
if err := c.writeLine(ctx, password); err != nil {
return fmt.Errorf("sending password: %w", err)
}
// Post-auth: look quickly for explicit failure, else accept shell prompt / silence.
match, got, err := c.readUntil(ctx,
append(append([]string{}, c.FailBanners...), c.ShellPrompts...)...,
)
if err != nil && !errors.Is(err, context.DeadlineExceeded) {View on GitHub (pinned to 265b3a3dec)
Solutions
- Increase the ctx deadline passed to Auth — WAN targets commonly need 10-30s to reach the prompt
- Widen c.UserPrompts to match the actual banner (capture it with `telnet target` or a raw read first, then add the exact string, case-insensitively)
- Confirm the port actually speaks interactive telnet login before calling Auth; skip non-login services
- Distinguish outcomes in the wrapped error: DeadlineExceeded = no prompt in time; EOF/reset = server dropped — different remediations
Example fix
// before ctx, cancel := context.WithTimeout(ctx, 3*time.Second) err := client.Auth(ctx, user, pass) // after client.UserPrompts = append(client.UserPrompts, "account:", "username->") ctx, cancel := context.WithTimeout(ctx, 20*time.Second) err := client.Auth(ctx, user, pass)
Defensive patterns
Strategy: retry
Validate before calling
// Capture the banner once and extend prompts to match before authing: client.UserPrompts = append(client.UserPrompts, "login:", "username:", "account:", "user->") ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
Type guard
func hasPrompt(banner string, prompts []string) bool {
low := strings.ToLower(banner)
for _, p := range prompts {
if strings.Contains(low, p) { return true }
}
return false
} Try / catch
err := client.Auth(ctx, user, pass)
if err != nil {
if errors.Is(err, context.DeadlineExceeded) || strings.Contains(err.Error(), "waiting for login/username prompt") {
// retry once with a longer deadline and wider prompt set, else classify as non-login service
return retryAuthWithLongerDeadline()
}
return err
} Prevention
- Set generous ctx deadlines (10-30s) for WAN telnet targets
- Read the banner first and configure UserPrompts to its exact wording (match is case-insensitive)
- Verify the port is an interactive login service before attempting auth
- Treat prompt-timeout as 'service not login telnet' — a classification, not a crash
When it happens
Trigger: The service never prints a prompt matching c.UserPrompts within the ctx deadline: a non-login service on the port (raw TCP banner, embedded device shell that needs a keypress), prompts with different wording (e.g. 'Login:', 'Account:', 'Username->' when defaults only cover common variants), slow/PAUSE-before-prompt servers, or the server closing the connection (read error instead of timeout).
Common situations: Telnet brute-force/info templates run against mixed fleets where many port-23 services are not classic Unix login prompts; ctx deadline set too tight (sub-second) for WAN latency; default prompt lists not covering the target's exact banner string.
Related errors
- NTLM response not properly terminated with Sub-option End
- failed to read response: %w
- NTLMSSP signature not found in response
- NTLM response too short: need at least 48 bytes, got %d
- expected NTLM challenge message, got type %d
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/49c37df6c1bb38b2.
Report an issue: GitHub.