{"record":{"id":"7d36d5077290d91f","repo":"NanmiCoder/MediaCrawler","slug":"get-ip-error-from-proxy-provider-and-status-code-n","errorCode":null,"errorMessage":"get ip error from proxy provider and status code not 200 ...","messagePattern":"get ip error from proxy provider and status code not 200 \\.\\.\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"proxy/providers/kuaidl_proxy.py","lineNumber":122,"sourceCode":"        \"\"\"\n        uri = \"/api/getdps/\"\n\n        # Prioritize getting IP from cache\n        ip_cache_list = self.ip_cache.load_all_ip(proxy_brand_name=self.proxy_brand_name)\n        if len(ip_cache_list) >= num:\n            return ip_cache_list[:num]\n\n        # If the quantity in cache is insufficient, get from IP provider to supplement, then store in cache\n        need_get_count = num - len(ip_cache_list)\n        self.params.update({\"num\": need_get_count})\n\n        ip_infos: List[IpInfoModel] = []\n        async with make_async_client() as client:\n            response = await client.get(self.api_base + uri, params=self.params)\n\n            if response.status_code != 200:\n                utils.logger.error(f\"[KuaiDaiLiProxy.get_proxies] statuc code not 200 and response.txt:{response.text}, status code: {response.status_code}\")\n                raise Exception(\"get ip error from proxy provider and status code not 200 ...\")\n\n            ip_response: Dict = response.json()\n            if ip_response.get(\"code\") != 0:\n                utils.logger.error(f\"[KuaiDaiLiProxy.get_proxies]  code not 0 and msg:{ip_response.get('msg')}\")\n                raise Exception(\"get ip error from proxy provider and  code not 0 ...\")\n\n            proxy_list: List[str] = ip_response.get(\"data\", {}).get(\"proxy_list\")\n            for proxy in proxy_list:\n                proxy_model = parse_kuaidaili_proxy(proxy)\n                # expire_ts is relative time (seconds), needs to be converted to absolute timestamp\n                # Consider expired DELTA_EXPIRED_SECOND seconds in advance to avoid critical time usage failure\n                ip_info_model = IpInfoModel(\n                    ip=proxy_model.ip,\n                    port=proxy_model.port,\n                    user=self.kdl_user_name,\n                    password=self.kdl_user_pwd,\n                    expired_time_ts=proxy_model.expire_ts + utils.get_unix_timestamp() - DELTA_EXPIRED_SECOND,\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/NanmiCoder/MediaCrawler/blob/d6f7c5bb906b6dac40ddf343ef9e26438a3de092/proxy/providers/kuaidl_proxy.py#L104-L140","documentation":"Raised in KuaiDaiLiProxy.get_proxies() when the HTTP request to the KuaiDaiLi API (api_base + uri with self.params) returns a non-200 status code. The full response body is logged beforehand via utils.logger.error, so the provider's own error text is available in logs. This is a transport/auth-level failure, distinct from a 200 response whose JSON body carries a non-zero code.","triggerScenarios":"GET to the KuaiDaiLi /GetKdlIp endpoint with invalid or expired signature/secret params (401/403), frequency-limit breach (429 or KuaiDaili's custom status), missing whitelist of your server IP in the KuaiDaiLi console, or network egress blocked so an intermediary returns 4xx/5xx.","commonSituations":"KuaiDaiLi account credentials (KDL_SECRET_ID / KDL_SIGNATURE) rotated or expired; the crawler server IP not added to the provider's IP whitelist; running many concurrent crawlers that exceed the extraction QPS; corporate firewall/proxy mangling the request.","solutions":["Read the logged response.text — KuaiDaili usually states the exact reason (auth failure, IP not whitelisted, rate limit)","Add the outbound server IP to the KuaiDaili account's IP whitelist and retry","Verify KDL_SECRET_ID / KDL_SIGNATURE env vars match the current KuaiDaili order credentials","Throttle get_proxies() calls or raise the interval to stay under the order's extraction frequency","Wrap the call in a retry with backoff for transient 5xx/429 responses"],"exampleFix":"// before\nresponse = await client.get(self.api_base + uri, params=self.params)\nif response.status_code != 200:\n    raise Exception(\"get ip error from proxy provider and status code not 200 ...\")\n\n// after\nresponse = await client.get(self.api_base + uri, params=self.params)\nif response.status_code in (429, 502, 503):\n    await asyncio.sleep(2)\n    response = await client.get(self.api_base + uri, params=self.params)\nif response.status_code != 200:\n    raise IpGetError(f\"kdl http {response.status_code}: {response.text[:200]}\")","handlingStrategy":"retry","validationCode":"async def kdl_api_reachable(client) -> bool:\n    try:\n        r = await client.get(api_base + health_uri, timeout=5)\n        return r.status_code < 500\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"for attempt in range(3):\n    try:\n        return await kdl.get_proxies(num=n)\n    except Exception as e:  # status!=200 path\n        if attempt == 2:\n            raise\n        utils.logger.warning(f\"kdl http error, backoff retry {attempt+1}: {e}\")\n        await asyncio.sleep(2 ** attempt)","preventionTips":["Whitelist your server's outbound IP in the KuaiDaili console before crawling","Keep KDL credentials in env vars and rotate them when the order changes","Cache fetched IPs so one HTTP failure doesn't stall the crawl (the pool already caches)"],"tags":["proxy","kuaidaili","http","auth","rate-limit"],"backgroundTag":null,"analyzedSha":"d6f7c5bb906b6dac40ddf343ef9e26438a3de092","analyzedAt":"2026-08-15T01:39:07.505Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}