projectdiscovery/subfinder · warning

results truncated at

Error message

results truncated at %d subdomains, more exist

What it means

The crt.sh-style CT (certificate transparency) source caps its output at subdomainLimit entries. When the API response reports Truncated, the source emits an Error-type result stating the list was cut short instead of silently returning partial results. It is informational: results before the cap are still valid.

Solutions

  1. Treat as informational — the returned subdomains up to the cap are valid
  2. Narrow the enumeration scope (per-host queries, filters) to stay under the cap
  3. Cross-check with other CT sources or direct brute force for the remaining entries
  4. Increase the limit if your build/config allows and the API supports it
Defensive patterns

Strategy: type-guard

Validate before calling

// caller-side: detect the truncation marker in results
for _, r := range results {
	if r.Type == subscraping.Error && strings.Contains(r.Error.Error(), "results truncated") {
		// merge additional sources for full coverage
	}
}

Type guard

func isTruncatedCTResult(r subscraping.Result) bool {
	return r.Type == subscraping.Error && strings.Contains(r.Error.Error(), "results truncated at")
}

Prevention

When it happens

Trigger: body.Truncated is true in the API response — the domain has more than subdomainLimit matching subdomains in CT logs, so the API cut the list at the limit.

Common situations: Enumerating very large domains (e.g. *.github.com, big SaaS hosts) where CT logs contain thousands of entries; wide wildcard certificates producing enormous subdomain sets.

Related errors


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

Appendix: source

Thrown at pkg/subscraping/sources/scanmalware/scanmalware.go:129

		return
	}

	var body ctDNSResponse
	err = jsoniter.NewDecoder(resp.Body).Decode(&body)
	if err != nil {
		results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
		s.errors++
		s.closeBody(resp, results)
		return
	}
	s.closeBody(resp, results)

	// The API caps the list and says so. Report the cap rather than presenting a
	// truncated list as complete.
	if body.Truncated {
		results <- subscraping.Result{
			Source: s.Name(), Type: subscraping.Error,
			Error: fmt.Errorf("results truncated at %d subdomains, more exist", subdomainLimit),
		}
		s.errors++
	}

	s.emit(ctx, body.Subdomains, session, results)
}

// enumerateArchive reads hosts present in the public scan archive.
func (s *Source) enumerateArchive(ctx context.Context, domain string, session *subscraping.Session, results chan subscraping.Result) {
	for page := 1; page <= smqlMaxPages; page++ {
		query := url.Values{
			"q":     {"domain:*." + domain},
			"limit": {fmt.Sprint(smqlPageSize)},
			"page":  {fmt.Sprint(page)},
		}
		requestURL := "https://scanmalware.com/api/v1/search/smql?" + query.Encode()

		s.requests++

View on GitHub (pinned to 7a0b91f0fa)