projectdiscovery/nuclei · error

http: url must include scheme and host

Error message

http: url must include scheme and host

What it means

The URL parsed but lacks a scheme or a host: nuclei/http demands absolute URLs like 'https://example.com/path' because host policy needs a hostname to evaluate. Bare hosts ('example.com'), scheme-less paths ('/api'), protocol-relative URLs ('//example.com'), and empty strings all fail here.

Source

Thrown at pkg/js/libs/http/http.go:262

		MaxBodyBytes:    defaultMaxBodyBytes,
		headers:         make(http.Header),
	}
}

func (c *Client) do(ctx context.Context, method, rawURL, body string) (*Response, error) {
	c.init()

	executionID := executionIDFrom(ctx, c)
	if executionID == "" {
		return nil, fmt.Errorf("http: executionId not set")
	}

	parsed, err := url.Parse(rawURL)
	if err != nil {
		return nil, fmt.Errorf("http: invalid url: %w", err)
	}
	if parsed.Scheme == "" || parsed.Host == "" {
		return nil, fmt.Errorf("http: url must include scheme and host")
	}

	host := parsed.Hostname()
	if !protocolstate.IsHostAllowed(executionID, host) {
		return nil, protocolstate.ErrHostDenied.Msgf(host)
	}

	dialers := protocolstate.GetDialersWithId(executionID)
	if dialers == nil {
		return nil, fmt.Errorf("dialers not initialized for %s", executionID)
	}

	tlsConfig := &tls.Config{
		InsecureSkipVerify: true,
		MinVersion:         tls.VersionTLS10,
		Renegotiation:      tls.RenegotiateOnceAsClient,
	}
	if host != "" {

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Always include scheme and host: client.Get('https://' + host + path)
  2. Default the scheme when missing: if (!/^https?:\/\//.test(u)) u = 'https://' + u
  3. Skip the request entirely when an extracted URL is empty or path-only

Example fix

// before
const resp = client.Get(host); // 'example.com' -> no scheme/host

// after: normalize to an absolute URL first
let u = String(host || '').trim();
if (!/^https?:\/\//.test(u)) u = 'https://' + u.replace(/^\/+/, '');
const resp = client.Get(u);
Defensive patterns

Strategy: validation

Validate before calling

function toAbsoluteUrl(u) {
  const s = String(u || '').trim();
  if (!s) return null;
  return /^https?:\/\//.test(s) ? s : 'https://' + s.replace(/^\/+/, '');
}
const url = toAbsoluteUrl(candidate);
if (url) { const resp = client.Get(url); }

Type guard

const hasSchemeAndHost = (u) => /^https?:\/\/[^\s/]+/.test(String(u || '').trim());

Try / catch

try { const resp = client.Get(u); }
catch (e) { if (/must include scheme and host/.test(e.message || '')) { /* prepend https:// and host, then retry */ } }

Prevention

When it happens

Trigger: client.Get('example.com'); client.Get('/api/v1'); passing only the output of an extractor that captured a path or a Host-header value; scheme omitted because curl-style syntax felt natural; empty string.

Common situations: Template authors used to tools where the scheme is optional; concatenating a Host header value without a protocol; building URLs from parts where the scheme variable is unset.

Related errors


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