projectdiscovery/subfinder · error
%s, %s
Error message
%s, %s
What it means
The AlienVault source reports upstream API errors by combining the response's 'detail' and 'error' fields into a single error Result: fmt.Errorf("%s, %s", response.Detail, response.Error). This surfaces AlienVault's own API error message to the caller as a scraping Result of type Error.
Solutions
- Set a valid OTX API key in the subfinder provider config ($HOME/.config/subfinder/provider-config.yaml)
- Check your OTX account quota/usage and retry after backoff
- Retry later if OTX is having an outage; check OTX status
- Inspect the error text: the detail message usually names the exact problem (auth, quota, bad query)
Defensive patterns
Strategy: try-catch
Try / catch
for result := range results {
if result.Type == subscraping.Error {
gologger.Warning().Msgf("alienvault: %v", result.Error)
continue
}
// process result
} Prevention
- Keep a valid OTX API key configured
- Respect OTX rate limits
- Handle Error-type results gracefully per source
When it happens
Trigger: AlienVault OTX API returns a JSON body where response.Error is non-empty — typically invalid/missing OTX API key, or the API rejecting the request (quota, bad request).
Common situations: No OTX API key configured or key expired; hitting OTX rate limits; OTX API temporary outages or schema changes producing error fields in the payload.
Related errors
AI-assisted analysis of projectdiscovery/subfinder@7a0b91f0fa (2026-09-06).
Data as JSON: /api/errors/23327104d2d7cab5.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/subscraping/sources/alienvault/alienvault.go:73
s.errors++
session.DiscardHTTPResponse(resp)
return
}
var response alienvaultResponse
// Get the response body and decode
err = json.NewDecoder(resp.Body).Decode(&response)
if err != nil {
results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}
s.errors++
session.DiscardHTTPResponse(resp)
return
}
session.DiscardHTTPResponse(resp)
if response.Error != "" {
results <- subscraping.Result{
Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf("%s, %s", response.Detail, response.Error),
}
return
}
for _, record := range response.PassiveDNS {
select {
case <-ctx.Done():
return
case results <- subscraping.Result{Source: s.Name(), Type: subscraping.Subdomain, Value: record.Hostname}:
s.results++
}
}
}()
return results
}
// Name returns the name of the sourceView on GitHub (pinned to 7a0b91f0fa)