projectdiscovery/nuclei · error

no new line found at the end of host header

Error message

no new line found at the end of host header

What it means

When nuclei splices rewritten headers into a raw request (e.g. host-header based injection), it locates the Host header line and needs its trailing newline to know where to insert. If the Host header exists but no newline terminates that line — the request text simply ends or continues without CRLF/LF — this error is returned.

Source

Thrown at pkg/protocols/http/raw/raw.go:339

		// attempt to locate next newline
		newLineIndex := bytes.Index(unsafeBytes[hostHeaderIndex:], []byte("\r\n"))
		if newLineIndex > 0 {
			newLineIndex += hostHeaderIndex + 2
			// insert custom headers
			buf := bufferPool.Get().(*bytes.Buffer)
			buf.Reset()
			buf.Write(r.UnsafeRawBytes[:newLineIndex])
			for _, header := range headers {
				buf.WriteString(header)
				buf.WriteString("\r\n")
			}
			buf.Write(r.UnsafeRawBytes[newLineIndex:])
			r.UnsafeRawBytes = append([]byte(nil), buf.Bytes()...)
			buf.Reset()
			bufferPool.Put(buf)
			return nil
		}
		return errors.New("no new line found at the end of host header")
	}

	return errors.New("no host header found")
}

// ApplyAuthStrategy applies the auth strategy to the request
func (r *Request) ApplyAuthStrategy(strategy authx.AuthStrategy) {
	if strategy == nil {
		return
	}
	switch s := strategy.(type) {
	case *authx.QueryAuthStrategy:
		parsed, err := urlutil.Parse(r.FullURL)
		if err != nil {
			gologger.Error().Msgf("auth strategy failed to parse url: %s got %v", r.FullURL, err)
			return
		}
		for _, p := range s.Data.Params {

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Terminate the Host header line with \r\n and keep the standard blank line separating headers from body (\r\n\r\n)
  2. Write raw requests with explicit CRLF endings exactly as they go on the wire
  3. Run `nuclei -t tpl.yaml -validate` and prefer building raw requests in Burp/hitbcapture then pasting with headers intact

Example fix

# before
- raw:
    - |
      GET / HTTP/1.1
      Host: {{Hostname}}

# after
- raw:
    - |
      GET / HTTP/1.1
      Host: {{Hostname}}

Defensive patterns

Strategy: validation

Validate before calling

// validate raw request text has a newline-terminated Host header
func hostHeaderTerminated(raw string) bool {
    i := strings.Index(strings.ToLower(raw), "host:")
    if i < 0 { return false }
    rest := raw[i:]
    return strings.Contains(rest, "\r\n") || strings.Contains(rest, "\n")
}

Prevention

When it happens

Trigger: A hand-written raw request in a template where the Host line is the last line with no trailing \r\n, or line endings were collapsed to spaces when copy-pasting from curl/terminal. The Host header must be terminated by a newline for the rewrite to proceed.

Common situations: YAML block scalars losing the final CRLF; requests pasted from Burp where the blank line before the body was dropped; editors normalizing CRLF to nothing.

Related errors


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