projectdiscovery/nuclei · error
prompt not found (read cap reached)
Error message
prompt not found (read cap reached)
What it means
readUntil (pkg/utils/telnetmini/telnet.go:350) accumulates bytes and scans the lowercased buffer for the needles (prompts) you passed; if the buffer grows past Client.ReadCapBytes before any needle matches, it aborts with 'prompt not found (read cap reached)'. ReadCapBytes defaults to 64 KiB via Defaults() and is a memory safety cap for chatty endpoints. The partial text captured so far is returned with the error for diagnosis.
Source
Thrown at pkg/utils/telnetmini/telnet.go:350
}
}
}
default:
// NOP for other commands (IAC NOP, GA, etc.)
}
continue
}
// regular data byte
b.WriteByte(tmp[0])
lower := strings.ToLower(b.String())
for i, n := range lowNeedles {
if strings.Contains(lower, n) {
return needles[i], b.String(), nil
}
}
if b.Len() > c.ReadCapBytes {
return "", b.String(), errors.New("prompt not found (read cap reached)")
}
}
}
func (c *Client) setDeadlineFromCtx(ctx context.Context, write bool) {
if ctx == nil {
return
}
if dl, ok := ctx.Deadline(); ok {
_ = c.Conn.SetReadDeadline(dl)
if write {
_ = c.Conn.SetWriteDeadline(dl)
}
}
}
func preview(s string, n int) string {
if len(s) <= n {View on GitHub (pinned to 265b3a3dec)
Solutions
- Pass the exact prompt string(s) the device prints as the `until` arguments to Exec
- Disable paging on the device first (e.g. `terminal length 0` on IOS) so output ends at the prompt
- Raise Client.ReadCapBytes when legitimate output exceeds 64 KiB
- Always set a ctx deadline so a truly missing prompt surfaces as context.DeadlineExceeded with partial output
Example fix
// before c.ReadCapBytes = 4 * 1024 out, err := c.Exec(ctx, "show version", "#") // after c.ReadCapBytes = 512 * 1024 out, err := c.Exec(ctx, "terminal length 0\nshow version", "router# ")
Defensive patterns
Strategy: validation
Validate before calling
// sanity-check client config before issuing commands
c.Defaults() // ensures ReadCapBytes == 64 KiB and non-empty prompts
if len(c.ShellPrompts) == 0 {
return errors.New("no shell prompts configured; Exec will hit read cap")
}
if c.ReadCapBytes < len(expectedOutput) {
c.ReadCapBytes = 2 * len(expectedOutput)
} Try / catch
out, err := c.Exec(ctx, cmd, "router# ")
if err != nil {
if strings.Contains(err.Error(), "read cap reached") {
// partial output is in `out`: inspect it to find the real prompt, adjust needles, retry once
return retryWithPrompt(out)
}
return err
} Prevention
- Pass the device's exact prompt (including trailing space) as the until needles
- Disable paging (terminal length 0) before commands that produce long output
- Size ReadCapBytes to the worst-case command output
- Always give Exec a ctx deadline
When it happens
Trigger: Client.Exec(ctx, cmd, until...) where none of the `until` prompts appears in output; verbose commands (show-tech, large listings) exceeding 64 KiB; ReadCapBytes set small; prompt needles with different spacing/case than what the device prints (matching is on the lowercased accumulated string).
Common situations: Network templates running commands on devices with custom PS1 prompts; pager output ('--More--') interleaving; forgetting `terminal length 0`; banners repeating on every screen.
Related errors
- authentication failed
- include directive preprocessing is disabled
- could not read profile file: %w
- could not parse profile YAML: %w
- could not marshal inline secrets: %w
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/a2fbc80a6b41fcbe.
Report an issue: GitHub.