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

  1. Increase the ctx deadline passed to Auth — WAN targets commonly need 10-30s to reach the prompt
  2. 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)
  3. Confirm the port actually speaks interactive telnet login before calling Auth; skip non-login services
  4. 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

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


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/49c37df6c1bb38b2. Report an issue: GitHub.