projectdiscovery/subfinder · error

failed to marshal request body

Error message

failed to marshal request body: %w

What it means

PugRecon source marshals {"domain_name": <domain>} as the POST body. If json.Marshal fails, an Error result wrapping the original error is emitted and enumeration stops for this source. With a simple map[string]string this is effectively unreachable except in broken builds.

Solutions

  1. Verify the postData map contains only marshalable string values
  2. Rebuild from unmodified upstream pugrecon.go
  3. Read the wrapped %w cause in the error result to identify the offending field
Defensive patterns

Strategy: validation

Validate before calling

// postData is map[string]string — always marshalable; validate domain non-empty before building
if domain == "" { return errors.New("domain is required") }

Try / catch

if err != nil {
	return fmt.Errorf("failed to marshal request body: %w", err)
}

Prevention

When it happens

Trigger: json.Marshal(postData) errors while preparing the PugRecon POST request for a domain — practically only with a modified payload structure containing non-marshalable values.

Common situations: Custom forks that added unsupported field types; corrupted toolchain builds; essentially never in stock subfinder.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of projectdiscovery/subfinder@7a0b91f0fa (2026-09-06). Data as JSON: /api/errors/16094ab6d836360a. Report an issue: GitHub.

Appendix: source

Thrown at pkg/subscraping/sources/pugrecon/pugrecon.go:62

	s.requests = 0

	go func() {
		defer func(startTime time.Time) {
			s.timeTaken = time.Since(startTime)
			close(results)
		}(time.Now())

		randomApiKey := subscraping.PickRandom(s.apiKeys, s.Name())
		if randomApiKey == "" {
			s.skipped = true
			return
		}

		// Prepare POST request data
		postData := map[string]string{"domain_name": domain}
		bodyBytes, err := json.Marshal(postData)
		if err != nil {
			results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("failed to marshal request body: %w", err)}
			s.errors++
			return
		}
		bodyReader := bytes.NewReader(bodyBytes)

		// Prepare headers
		headers := map[string]string{
			"Authorization": "Bearer " + randomApiKey,
			"Content-Type":  "application/json",
			"Accept":        "application/json",
		}

		apiURL := "https://pugrecon.com/api/v1/domains"
		s.requests++
		resp, err := session.HTTPRequest(ctx, http.MethodPost, apiURL, "", headers, bodyReader, subscraping.BasicAuth{}) // Use HTTPRequest for full header control
		if err != nil {
			results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
			s.errors++

View on GitHub (pinned to 7a0b91f0fa)