projectdiscovery/nuclei · error
sending password: %w
Error message
sending password: %w
What it means
Writing the password line to the telnet connection failed. After the password prompt matched, Client.Auth calls writeLine(ctx, password); the returned error wraps the underlying net.Conn write failure (broken pipe, connection reset, closed conn, or ctx canceled). This is a transport-level failure, not an authentication verdict.
Source
Thrown at pkg/utils/telnetmini/telnet.go:222
// 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) {
return fmt.Errorf("post-auth read: %s (got: %s)", preview(got, 200), err)
}
low := strings.ToLower(match)
for _, fb := range c.FailBanners {
if low == strings.ToLower(fb) {
return errors.New("authentication failed")
}
}
// success (matched a shell prompt or timed out without explicit failure)
return nil
}View on GitHub (pinned to 265b3a3dec)
Solutions
- Retry with a fresh Client/connection — a mid-handshake reset is usually transient or a session-limit signal.
- Check whether the server allows more than one concurrent telnet session and close stale sessions.
- Ensure ctx is not already expired when Auth is called (the same ctx bounds every read and write in the handshake).
- If the server closes on username, revisit UserPrompts — the wrong value may have been sent as the username.
Example fix
// before
_ = client.Auth(ctx, user, pass)
// after
if err := client.Auth(ctx, user, pass); err != nil {
if strings.Contains(err.Error(), "sending password") {
client.Close()
// reconnect once; server dropped us mid-handshake
}
} Defensive patterns
Strategy: retry
Validate before calling
// nothing to validate client-side beyond connection liveness
if err := client.Ping(ctx); err != nil { /* skip Auth, target is unhealthy */ } Type guard
func isTelnetWriteErr(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "sending password:")
} Try / catch
if err := client.Auth(ctx, user, pass); err != nil {
if isTelnetWriteErr(err) {
client.Close()
// one reconnect+retry; a mid-handshake reset is often transient or a session cap
}
} Prevention
- Close and reopen the Client between attempts; a dead conn cannot be written to.
- Avoid canceling the parent ctx during the auth handshake.
- Cap retries (1) — repeated resets mean the server refuses the session, not a flake.
When it happens
Trigger: Server closes the connection immediately after printing the password prompt (some services do this on max sessions or bad TTY negotiation), ctx is canceled/expired before the write, or the conn was already torn down by the remote end or an intermediary.
Common situations: Remote device enforcing a single telnet session (kicks the new one), NAT/idle timeout killing the session mid-handshake, or test harnesses against mock listeners that accept but immediately close.
Related errors
- authentication failed
- failed to send encryption packet: %w
- waiting for password prompt: %w
- post-auth read: %s (got: %s)
- prompt not found (read cap reached)
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/2d517800d1f0b815.
Report an issue: GitHub.