{"record":{"id":"ae22b18560dc0b73","repo":"sundowndev/phoneinfoga","slug":"rate-limit-exceeded-see-https-developers-google","errorCode":null,"errorMessage":"rate limit exceeded, see https://developers.google.com/custom-search/v1/overview#pricing","messagePattern":"rate limit exceeded, see https://developers\\.google\\.com/custom-search/v1/overview#pricing","errorType":"http","errorClass":null,"httpStatus":429,"severity":"error","filePath":"lib/remote/googlecse_scanner.go","lineNumber":96,"sourceCode":"\tvar cx = opts.GetStringEnv(\"GOOGLECSE_CX\")\n\tvar apikey = opts.GetStringEnv(\"GOOGLE_API_KEY\")\n\n\tdorks = append(dorks, s.generateDorkQueries(n)...)\n\n\tcustomsearchService, err := customsearch.NewService(\n\t\tcontext.Background(),\n\t\toption.WithAPIKey(apikey),\n\t\toption.WithHTTPClient(s.httpClient),\n\t)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tfor _, req := range dorks {\n\t\tn, items, err := s.search(customsearchService, req.Dork, cx)\n\t\tif err != nil {\n\t\t\tif s.isRateLimit(err) {\n\t\t\t\treturn nil, errors.New(\"rate limit exceeded, see https://developers.google.com/custom-search/v1/overview#pricing\")\n\t\t\t}\n\t\t\treturn nil, err\n\t\t}\n\t\tallItems = append(allItems, items...)\n\t\ttotalResultCount += n\n\t\ttotalRequestCount++\n\t}\n\n\tvar data GoogleCSEScannerResponse\n\tfor _, item := range allItems {\n\t\tdata.Items = append(data.Items, ResultItem{\n\t\t\tTitle: item.Title,\n\t\t\tURL:   item.Link,\n\t\t})\n\t}\n\tdata.Homepage = fmt.Sprintf(\"https://cse.google.com/cse?cx=%s\", cx)\n\tdata.ResultCount = len(allItems)\n\tdata.TotalResultCount = totalResultCount","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/sundowndev/phoneinfoga/blob/55807b05b753dab7bc6fe67403ca385668dda179/lib/remote/googlecse_scanner.go#L78-L114","documentation":"During Run, each dork query goes through the Google Custom Search JSON API; when s.isRateLimit(err) detects a rate-limit/quota HTTP error, the scanner replaces the raw API error with 'rate limit exceeded, see https://developers.google.com/custom-search/v1/overview#pricing'.","triggerScenarios":"Issuing more Custom Search queries than the quota allows: exceeding 100 free queries/day, or the per-100-seconds user/project limits, while iterating over multiple dorks for one number.","commonSituations":"Scanning many phone numbers in a loop in one day, sharing one API key across team/projects so the project quota is exhausted, or paid quota not enabled in the Google Cloud console.","solutions":["Wait until the quota window resets (daily quota resets at midnight Pacific Time) and retry","Enable paid billing for Custom Search JSON API to raise the daily query cap","Reduce query volume: limit scanners/dorks per run, cache results, or add delays between scans","Use a different Google Cloud project/API key with remaining quota"],"exampleFix":"// before\nfor n in $(cat numbers.txt); do scan --number $n; done   # quota exhausted after ~100 queries\n// after\nfor n in $(cat numbers.txt); do scan --number $n; sleep 60; done  # spread usage, monitor quota in Cloud Console","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, err := scanner.Run(num, opts)\nif err != nil && strings.Contains(err.Error(), \"rate limit exceeded\") {\n    // exponential backoff, then reschedule after quota window\n    time.Sleep(backoff)\n    return retry(num)\n}\nreturn err","preventionTips":["Monitor your Custom Search quota in Google Cloud Console daily","Cap the number of googlecse scans per day (free tier: ~100 queries)","Batch numbers and add delays between scans","Enable paid quota before running bulk scans"],"tags":["google-cse","rate-limit","quota","network"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"55807b05b753dab7bc6fe67403ca385668dda179","analyzedAt":"2026-09-03T13:37:27.908Z","contentChangedAt":"2026-09-03T13:37:27.908Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}