projectdiscovery/nuclei · error
post-auth read: %s (got: %s)
Error message
post-auth read: %s (got: %s)
What it means
The post-authentication read returned an error other than context.DeadlineExceeded. Auth deliberately tolerates a timeout after sending credentials (silence is treated as success), so this error fires only for real I/O failures — connection reset, EOF, or a canceled context — while scanning for FailBanners vs ShellPrompts. Note the message is formatted with %s (preview of bytes received) rather than wrapping the error with %w.
Source
Thrown at pkg/utils/telnetmini/telnet.go:230
}
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
}
// Exec sends a command followed by CRLF and returns text captured until one of
// the provided prompts appears (typically your shell prompt). Provide a deadline via ctx.
func (c *Client) Exec(ctx context.Context, command string, until ...string) (string, error) {
if err := c.writeLine(ctx, command); err != nil {
return "", err
}
_, out, err := c.readUntil(ctx, until...)View on GitHub (pinned to 265b3a3dec)
Solutions
- Treat a reset-after-credentials as an authentication failure or target-level defect: verify credentials manually (e.g. with a telnet client) to see whether the socket reset is the server's reject behavior.
- Confirm you are speaking plain telnet and not TLS/SSH — a TLS or SSH greeting will never match the configured prompts and can cause an abnormal teardown.
- If ctx.Canceled is being produced by your own supervisor, avoid canceling Auth mid-flight or map it to a clean abort path.
- Extend the ctx budget so slow post-login banner output is not misread as failure.
Example fix
// before
err := client.Auth(ctx, user, pass)
// after
err := client.Auth(ctx, user, pass)
if err != nil && strings.Contains(err.Error(), "post-auth read") {
// socket died scanning for fail/shell banners; count as failed auth for this host
log.Printf("host %s reset after auth: %v", host, err)
} Defensive patterns
Strategy: try-catch
Type guard
func isPostAuthReadErr(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "post-auth read:")
} Try / catch
err := client.Auth(ctx, user, pass)
if isPostAuthReadErr(err) {
// transport died scanning fail/shell banners: treat as auth failure for this host
log.Printf("%s: post-auth drop: %v", host, err)
} Prevention
- Remember timeouts are tolerated here — only real I/O errors surface, so do not 'fix' by raising the deadline alone.
- Verify credentials against the same host manually to learn whether reset == reject.
- Do not unwrap with errors.Is/%w — the message embeds err via %s, so match on prefix.
When it happens
Trigger: The remote end drops the TCP connection right after credentials are submitted (banner-based auth rejection, service crash, PAM failure without a banner), or ctx is canceled (context.Canceled, not DeadlineExceeded) during the final read.
Common situations: Devices that reset the socket instead of printing a failure banner on bad credentials; aggressive per-attempt ctx cancellation from a scanner supervisor; TLS-wrapped services mistakenly spoken to as plain telnet.
Related errors
- authentication failed
- waiting for password prompt: %w
- sending password: %w
- prompt not found (read cap reached)
- smb connect: %w
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/cdacd6af26dae2b4.
Report an issue: GitHub.