{"record":{"id":"2143f553784ae26a","repo":"projectdiscovery/subfinder","slug":"s-2143f5","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/subscraping/sources/pugrecon/pugrecon.go","lineNumber":98,"sourceCode":"\t\t\ts.errors++\n\t\t\tsession.DiscardHTTPResponse(resp)\n\t\t\treturn\n\t\t}\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: fmt.Errorf(\"failed to close response body: %w\", 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\terrorMsg := fmt.Sprintf(\"received status code %d\", resp.StatusCode)\n\t\t\t// Attempt to read error message from body if possible\n\t\t\tvar apiResp pugreconAPIResponse\n\t\t\tif json.NewDecoder(resp.Body).Decode(&apiResp) == nil && apiResp.Message != \"\" {\n\t\t\t\terrorMsg = fmt.Sprintf(\"%s: %s\", errorMsg, apiResp.Message)\n\t\t\t}\n\t\t\tresults <- subscraping.Result{Source: s.Name(), Type: subscraping.Error, Error: fmt.Errorf(\"%s\", errorMsg)}\n\t\t\ts.errors++\n\t\t\treturn\n\t\t}\n\n\t\tvar response pugreconAPIResponse\n\t\terr = json.NewDecoder(resp.Body).Decode(&response)\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\tfor _, subdomain := range response.Results {\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: subdomain.Name}:\n\t\t\t\ts.results++","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/projectdiscovery/subfinder/blob/7a0b91f0fac01b62c65328bd771a3560ae611d6a/pkg/subscraping/sources/pugrecon/pugrecon.go#L80-L116","documentation":"PugRecon received a non-200 HTTP status from its API. The source builds an error message with the status code and, if the body decodes as the API response with a Message field, appends the API's message (e.g. quota or auth errors). This is the source's generic API-error channel.","triggerScenarios":"The POST to the PugRecon API returns a status other than 200 (401 invalid/expired session token, 402/429 quota exceeded, 5xx server error); the response Message is appended when present.","commonSituations":"Expired or missing Pugrecon session/auth token in config; exhausted API quota on a free plan; PugRecon outage causing 5xx.","solutions":["Read the appended API message after the status code for the exact cause","Renew or correct the PugRecon API token in subfinder config (provider-settings)","Check your PugRecon plan quota; upgrade or wait for reset if quota exceeded","Retry later if the status is 5xx (server-side outage)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// pre-validate config\nif token == \"\" { return errors.New(\"pugrecon API key missing in provider config\") }","typeGuard":null,"tryCatchPattern":"// inspect the appended API message to branch\nif strings.Contains(errMsg, \"quota\") {\n\t// wait for reset / upgrade plan\n} else if resp.StatusCode == 401 {\n\t// refresh token\n}","preventionTips":["Keep the PugRecon API token current in provider settings","Monitor plan quota before bulk enumeration","Handle 5xx with delayed retries"],"tags":["go","http","api-error"],"backgroundTag":"http-error-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"}