shadow1ng/fscan · error

webscan_request_execute_failed

webscan_request_execute_failed

Error message

webscan_request_execute_failed: %w

What it means

DoRequest failed to execute the outbound HTTP request during POC evaluation. When the underlying http client (including GMTLS fallback) returns an error, the library records a failed TCP packet in the scan state and wraps the transport error with the i18n message webscan_request_execute_failed. This is the library's umbrella error for any network-level failure while sending a POC request.

Source

Thrown at webscan/lib/Eval.go:537

		if redirect {
			if clientGM := gmRequestClient(true); clientGM != nil {
				if oResp2, err2 := clientGM.Do(req); err2 == nil {
					oResp, err = oResp2, nil
				}
			}
		} else {
			if clientGM := gmRequestClient(false); clientGM != nil {
				if oResp2, err2 := clientGM.Do(req); err2 == nil {
					oResp, err = oResp2, nil
				}
			}
		}
	}

	if err != nil {
		// HTTP请求失败,计为TCP失败
		state.IncrementTCPFailedPacketCount()
		return nil, fmt.Errorf("%s: %w", i18n.GetText("webscan_request_execute_failed"), err)
	}

	// HTTP请求成功,计为TCP成功
	state.IncrementTCPSuccessPacketCount()
	defer func() { _ = oResp.Body.Close() }()

	// 解析响应
	resp, err := ParseResponse(oResp)
	if err != nil {
		common.LogError(i18n.Tr("webscan_response_parse_failed", err))
	}

	return resp, err
}

func requestClient(redirect bool) *http.Client {
	if redirect {
		if Client != nil {

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Unwrap the error (%w) with errors.Unwrap to see the underlying cause and fix that first (connect refused, timeout, DNS, TLS).
  2. Verify the target host:port is reachable with curl/nc before scanning.
  3. Check proxy and timeout configuration used by the scanner's HTTP clients.
  4. Ensure the global client or GMTLS fallback client is properly initialized; tests show DoRequest falls back when the global client is nil.
  5. Add retry logic for transient network failures, since the scan state already tracks TCP failures.

Example fix

// before
resp, err := DoRequest(req)
if err != nil { return err }

// after
resp, err := DoRequest(req)
var netErr net.Error
if errors.As(err, &netErr) && netErr.Timeout() {
    resp, err = DoRequest(req) // retry transient timeouts
}
if err != nil {
    return fmt.Errorf("request to %s failed: %w", req.URL, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

conn, err := net.DialTimeout("tcp", host+":"+port, 3*time.Second)
if err != nil { return fmt.Errorf("target unreachable: %w", err) }
conn.Close()

Try / catch

if _, err := DoRequest(req); err != nil {
    var netErr net.Error
    switch {
    case errors.As(err, &netErr) && netErr.Timeout():
        // retry with backoff
    default:
        // mark target unreachable, continue scan
    }
}

Prevention

When it happens

Trigger: DoRequest's client.Do/transport round-trip returns a non-nil error: connection refused, DNS failure, TLS/GMTLS handshake failure, request timeout, or nil global client with no usable fallback client.

Common situations: Scanning hosts behind firewalls; target ports closed; misconfigured proxy or timeout settings; GMTLS fallback client unavailable (global client nil and fallback skipped); target resolves but drops packets.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/dc9f45994136a45d. Report an issue: GitHub.