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.

Solutions

  1. Pass the exact prompt string(s) the device prints as the `until` arguments to Exec
  2. Disable paging on the device first (e.g. `terminal length 0` on IOS) so output ends at the prompt
  3. Raise Client.ReadCapBytes when legitimate output exceeds 64 KiB
  4. 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

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


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

Appendix: 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)