{"record":{"id":"cfcb4ba28d260524","repo":"projectdiscovery/subfinder","slug":"unexpected-status-code-d-received-from-s-cfcb4b","errorCode":null,"errorMessage":"unexpected status code %d received from %s","messagePattern":"unexpected status code (.+?) received from (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/subscraping/sources/shodanct/shodanct.go","lineNumber":49,"sourceCode":"\t\tdefer func(startTime time.Time) {\n\t\t\ts.timeTaken = time.Since(startTime)\n\t\t\tclose(results)\n\t\t}(time.Now())\n\n\t\tsearchURL := fmt.Sprintf(\"https://ctl.shodan.io/api/v1/domain/%s/hostnames\", domain)\n\t\ts.requests++\n\t\tresp, err := session.SimpleGet(ctx, searchURL)\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\tsession.DiscardHTTPResponse(resp)\n\t\t\treturn\n\t\t}\n\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\tresults <- subscraping.Result{\n\t\t\t\tSource: s.Name(), Type: subscraping.Error,\n\t\t\t\tError: fmt.Errorf(\"unexpected status code %d received from %s\", resp.StatusCode, searchURL),\n\t\t\t}\n\t\t\ts.errors++\n\t\t\tsession.DiscardHTTPResponse(resp)\n\t\t\treturn\n\t\t}\n\n\t\tdefer session.DiscardHTTPResponse(resp)\n\n\t\tvar hostnames []string\n\t\tif err := jsoniter.NewDecoder(resp.Body).Decode(&hostnames); 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\tfor _, hostname := range hostnames {\n\t\t\tfor _, subdomain := range session.Extractor.Extract(hostname) {\n\t\t\t\tselect {","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/projectdiscovery/subfinder/blob/7a0b91f0fac01b62c65328bd771a3560ae611d6a/pkg/subscraping/sources/shodanct/shodanct.go#L31-L67","documentation":"The shodanct (Shodan Certificate Transparency) source raises this when the HTTP response status is anything other than 200 OK from the searchURL. The library includes the actual status code and URL so the caller can see exactly which endpoint rejected the request.","triggerScenarios":"GET to the Shodan CT search URL returns a non-200 status: 401/403 for bad or missing API key, 429 for rate limiting, 5xx for server-side errors.","commonSituations":"Missing SHODANCT_API_KEY or wrong plan tier; invoking the source frequently and hitting rate limits; transient Shodan outages.","solutions":["Log/inspect resp.StatusCode to identify the class of failure (auth vs rate limit vs server error).","Ensure a valid Shodan API key is configured for the shodanct source.","Add backoff/retry for 429/5xx responses and reduce request frequency."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if os.Getenv(\"SHODAN_API_KEY\") == \"\" { log.Warn(\"shodanct will fail with non-200 status\") }","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 || code >= 500) {\n      // retry with exponential backoff\n    }\n  }\n}","preventionTips":["Check key validity and plan tier before enabling the shodanct source.","Throttle concurrent requests to Shodan endpoints.","Handle 429/5xx with backoff rather than immediate failure."],"tags":["network","http-status","shodan","api-request"],"backgroundTag":"http-non-200-response","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"}