{"record":{"id":"e2fc893d128d6112","repo":"projectdiscovery/subfinder","slug":"unexpected-status-code-d-e2fc89","errorCode":null,"errorMessage":"unexpected status code: %d","messagePattern":"unexpected status code: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/subscraping/sources/threatcrowd/threatcrowd.go","lineNumber":69,"sourceCode":"\t\tresp, err := session.Client.Do(req)\n\t\tif err != nil {\n\t\t\tresults <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}\n\t\t\ts.errors++\n\t\t\treturn\n\t\t}\n\t\t// This source issues a raw client.Do (bypassing the session's\n\t\t// httpRequestWrapper), so apply the response-body size cap explicitly\n\t\t// when configured (0 = unlimited).\n\t\tsubscraping.LimitResponseBody(resp, session.MaxResponseBodySize)\n\t\tdefer func() {\n\t\t\tif err := resp.Body.Close(); err != nil {\n\t\t\t\tresults <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}\n\t\t\t\ts.errors++\n\t\t\t}\n\t\t}()\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tresults <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf(\"unexpected status code: %d\", resp.StatusCode)}\n\t\t\ts.errors++\n\t\t\treturn\n\t\t}\n\n\t\tbody, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\tresults <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}\n\t\t\ts.errors++\n\t\t\treturn\n\t\t}\n\n\t\tvar tcResponse threatCrowdResponse\n\t\tif err := json.Unmarshal(body, &tcResponse); err != nil {\n\t\t\tresults <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: err}\n\t\t\ts.errors++\n\t\t\treturn\n\t\t}\n","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/projectdiscovery/subfinder/blob/7a0b91f0fac01b62c65328bd771a3560ae611d6a/pkg/subscraping/sources/threatcrowd/threatcrowd.go#L51-L87","documentation":"The threatcrowd source raises this when the HTTP response status is not 200 OK. ThreatCrowd's public API returns non-200 for rate limiting and outages, and the library converts the status code into an Error Result before attempting to parse the body.","triggerScenarios":"HTTP GET to the ThreatCrowd API returns any status other than 200 — most commonly 401/403 (key issues) or 429/5xx (rate limit or downtime).","commonSituations":"ThreatCrowd heavily rate-limits public queries; automated enumeration without throttling quickly triggers non-200 responses; the service has had extended outages/deprecations.","solutions":["Check resp.StatusCode and apply exponential backoff, especially for 429.","Disable or replace the threatcrowd source if the service is unavailable or deprecated.","Throttle requests well below the API's documented limits."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"for r := range results {\n  if r.Type == subscraping.Error {\n    var code int\n    if n, _ := fmt.Sscanf(r.Error.Error(), \"unexpected status code: %d\", &code); n == 1 && code == 429 {\n      // back off significantly and retry later\n    }\n  }\n}","preventionTips":["Heavily throttle ThreatCrowd requests; the public API rate-limits aggressively.","Disable the source when the service is down or deprecated.","Cache prior results to avoid repeat queries."],"tags":["network","http-status","threatcrowd","rate-limit"],"backgroundTag":"unexpected-http-status","analyzedSha":"7a0b91f0fac01b62c65328bd771a3560ae611d6a","analyzedAt":"2026-09-06T23:52:02.109Z","contentChangedAt":"2026-09-06T23:52:02.109Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}