projectdiscovery/nuclei · error

invalid method line: %s

Error message

invalid method line: %s

What it means

The first line of a raw request split on single spaces yielded fewer than 3 parts, so method, target, or HTTP version is missing. Nuclei requires 'METHOD SP TARGET SP VERSION' exactly; tabs or multiple spaces still count as separators only if they are literal single spaces in the split sense.

Source

Thrown at pkg/input/types/http.go:238

	}
}

// ParseRawRequest parses a raw request from a string
// and returns the request and response object
// Note: it currently does not parse response and is meant to be added manually since its a optional field
func ParseRawRequest(raw string) (rr *RequestResponse, err error) {
	protoReader := textproto.NewReader(bufio.NewReader(strings.NewReader(raw)))
	methodLine, err := protoReader.ReadLine()
	if err != nil {
		return nil, fmt.Errorf("failed to read method line: %s", err)
	}
	rr = &RequestResponse{
		Request: &HttpRequest{},
	}
	/// must contain at least 3 parts
	parts := strings.Split(methodLine, " ")
	if len(parts) < 3 {
		return nil, fmt.Errorf("invalid method line: %s", methodLine)
	}
	method := parts[0]
	rr.Request.Method = method

	// the request target is normally an origin-form path, but proxy captures and
	// .http files use the absolute form, which already carries the authority
	var urlx *urlutil.URL
	target := parts[1]
	if stringsutil.HasPrefixAnyI(target, urlutil.HTTP+urlutil.SchemeSeparator, urlutil.HTTPS+urlutil.SchemeSeparator) {
		// urlutil.ParseAbsoluteURL only accepts lowercase schemes; preserve the
		// remainder of the request target unchanged.
		if scheme, rest, ok := strings.Cut(target, urlutil.SchemeSeparator); ok {
			target = strings.ToLower(scheme) + urlutil.SchemeSeparator + rest
		}
		urlx, err = urlutil.ParseAbsoluteURL(target, true)
	} else {
		urlx, err = urlutil.ParseRawRelativePath(target, true)
	}

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Rewrite the first line as three space-separated parts, e.g. 'POST /login HTTP/1.1'
  2. Use plain ASCII spaces, not tabs, between the three parts
  3. Strip comment lines or editorial text above the request

Example fix

# before
raw: |
  GET /
  Host: example.com

# after
raw: |
  GET / HTTP/1.1
  Host: example.com
Defensive patterns

Strategy: validation

Validate before calling

first := strings.SplitN(raw, "\n", 2)[0]
parts := strings.Split(first, " ")
if len(parts) < 3 || parts[0] == "" || parts[1] == "" {
    return fmt.Errorf("method line malformed: %q", first)
}

Try / catch

Catch and repair: if the first line has 2 parts, append ' HTTP/1.1' and re-parse once; otherwise drop the entry.

Prevention

When it happens

Trigger: Lines like 'GET /' (no version), 'GET' alone, 'GET/' merged, or a first line that is actually prose or a comment pasted above the request.

Common situations: Editing raw requests in templates and deleting the version; proxy exports that drop HTTP/1.1; using commas or tabs instead of spaces; HTTP/2 pseudo-headers (':method: GET') pasted as the first line.

Related errors


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