projectdiscovery/nuclei · error
probe concurrency must be at least 1
Error message
probe concurrency must be at least 1
What it means
For raw HTTP requests nuclei bufio-reads the first line; any read error - an empty raw block, or a request line with no trailing newline so ReadString returns io.EOF - aborts with 'could not read request'. Annotation lines (@tls-SNI etc.) are skipped, but a real request line terminated by a newline must follow them.
Source
Thrown at lib/config.go:151
return errors.New("template threads must be at least 1")
}
if opts.HostConcurrency <= 0 {
return errors.New("host concurrency must be at least 1")
}
if opts.HeadlessHostConcurrency <= 0 {
return errors.New("headless host concurrency must be at least 1")
}
if opts.HeadlessTemplateConcurrency <= 0 {
return errors.New("headless template threads must be at least 1")
}
if opts.JavascriptTemplateConcurrency <= 0 {
return errors.New("js must be at least 1")
}
if opts.TemplatePayloadConcurrency <= 0 {
return errors.New("payload concurrency must be at least 1")
}
if opts.ProbeConcurrency <= 0 {
return errors.New("probe concurrency must be at least 1")
}
e.opts.TemplateThreads = opts.TemplateConcurrency
e.opts.BulkSize = opts.HostConcurrency
e.opts.HeadlessBulkSize = opts.HeadlessHostConcurrency
e.opts.HeadlessTemplateThreads = opts.HeadlessTemplateConcurrency
e.opts.JsConcurrency = opts.JavascriptTemplateConcurrency
e.opts.PayloadConcurrency = opts.TemplatePayloadConcurrency
e.opts.ProbeConcurrency = opts.ProbeConcurrency
return nil
}
}
// WithResponseReadSize sets the maximum size of response to read in bytes.
// A value of 0 means no limit. Recommended values: 1MB (1048576) to 10MB (10485760).
func WithResponseReadSize(responseReadSize int) NucleiSDKOptions {
return func(e *NucleiEngine) error {
if responseReadSize < 0 {
return errors.New("response read size must be non-negative")View on GitHub (pinned to 265b3a3dec)
Solutions
- Make the raw block start with a complete request line that ends with a newline
- Use a literal block (raw: |) so line breaks survive YAML parsing
- If only annotations exist, add at least a minimal request line (GET / HTTP/1.1)
- Validate with nuclei -validate
Example fix
# before
raw:
- "GET /path HTTP/1.1"
# after
raw:
- |
GET /path HTTP/1.1
Host: {{BaseURL}} Defensive patterns
Strategy: validation
Validate before calling
import "strings"
func rawRequestReadable(data string) bool {
if !strings.Contains(data, "\n") {
return false // no terminated first line
}
for _, line := range strings.Split(data, "\n") {
if !strings.HasPrefix(line, "@") && strings.TrimSpace(line) != "" {
return true // a real request line exists
}
}
return false
} Prevention
- Use raw: | literal blocks so newlines survive YAML
- Ensure the request line ends with a newline
- Validate templates before deploying them
When it happens
Trigger: A raw: block that is empty, contains only @annotation lines then EOF, or a quoted single-line scalar like "GET / HTTP/1.1" whose string lacks a final newline.
Common situations: Truncated raw templates; YAML quoted scalars collapsing newlines; copy-paste dropping the last line break.
Related errors
- response read size must be non-negative
- no new line found at the end of host header
- no host header found
- validation failed for these fields
- both verbose and silent mode specified
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/af2ed94a335c9e6c.
Report an issue: GitHub.