{"record":{"id":"b1e58f51150b1654","repo":"projectdiscovery/subfinder","slug":"request-failed-with-status-d-b1e58f","errorCode":null,"errorMessage":"request failed with status %d","messagePattern":"request failed with status (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/subscraping/sources/leakix/leakix.go","lineNumber":56,"sourceCode":"\t\t}\n\t\t// Pick an API key\n\t\trandomApiKey := subscraping.PickRandom(s.apiKeys, s.Name())\n\t\tif randomApiKey != \"\" {\n\t\t\theaders[\"api-key\"] = randomApiKey\n\t\t}\n\t\t// Request\n\t\ts.requests++\n\t\tresp, err := session.Get(ctx, \"https://leakix.net/api/subdomains/\"+domain, \"\", headers)\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\tdefer session.DiscardHTTPResponse(resp)\n\n\t\tif resp.StatusCode != 200 {\n\t\t\tresults <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf(\"request failed with status %d\", resp.StatusCode)}\n\t\t\ts.errors++\n\t\t\treturn\n\t\t}\n\t\t// Parse and return results\n\t\tvar subdomains []subResponse\n\t\tdecoder := json.NewDecoder(resp.Body)\n\t\terr = decoder.Decode(&subdomains)\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\tfor _, result := range subdomains {\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\treturn\n\t\t\tcase results <- subscraping.Result{Source: s.Name(), Type: subscraping.Subdomain, Value: result.Subdomain}:\n\t\t\t\ts.results++","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/projectdiscovery/subfinder/blob/7a0b91f0fac01b62c65328bd771a3560ae611d6a/pkg/subscraping/sources/leakix/leakix.go#L38-L74","documentation":"The LeakIX source requires HTTP 200 and treats every other status code as a hard failure: when resp.StatusCode != 200 it emits this error on the results channel and stops. It is a plain transport-level rejection by the LeakIX API (auth, rate limit, server error) with only the numeric status included — the response body is discarded.","triggerScenarios":"Any request to the LeakIX API that returns a non-200 status: missing/invalid LEAKIX_API_KEY (401/403), rate limiting (429), or server-side errors (5xx) during Fetch.","commonSituations":"Running without a LeakIX API key (anonymous tier heavily limited / 401), an expired or revoked key, aggressive enumeration triggering 429, or LeakIX API downtime returning 5xx.","solutions":["Log the response body alongside the status code to see LeakIX's actual error message","Check that LEAKIX_API_KEY is set and valid for your LeakIX account","Retry after backoff on 429/5xx; respect LeakIX rate limits","Check the LeakIX status page / API changelog for outages or endpoint changes"],"exampleFix":"// before\nif resp.StatusCode != 200 {\n    results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf(\"request failed with status %d\", resp.StatusCode)}\n    s.errors++\n    return\n}\n// after\nif resp.StatusCode != 200 {\n    body, _ := io.ReadAll(resp.Body)\n    results <- subscraping.Result{Source: s.Name(), Type: subscraping.Error,\n        Error: fmt.Errorf(\"request failed with status %d: %s\", resp.StatusCode, string(body))}\n    s.errors++\n    return\n}","handlingStrategy":"retry","validationCode":"if os.Getenv(\"LEAKIX_API_KEY\") == \"\" {\n    log.Println(\"warning: LEAKIX_API_KEY not set; leakix requests may return 401/403\")\n}","typeGuard":null,"tryCatchPattern":"for res := range src.Fetch(ctx, domain) {\n    if res.Type == subscraping.Error {\n        var statusErr interface{ Error() string }\n        msg := res.Error.Error()\n        if strings.Contains(msg, \"status 429\") {\n            time.Sleep(backoff) // rate limited — retry later\n        } else if strings.Contains(msg, \"status 5\") {\n            // transient server error — retry with backoff\n        } else {\n            log.Printf(\"leakix: %v (check LEAKIX_API_KEY)\", res.Error)\n        }\n    }\n}","preventionTips":["Set a valid LEAKIX_API_KEY before running enumeration","Throttle request rate to stay under LeakIX limits and back off on 429","Log full status codes and retry only transient classes (429, 5xx)","Watch LeakIX API status/changelog for endpoint or auth changes"],"tags":["network","http","api","status-code"],"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"}