Max Retries Exceeded With URL Hatası Nedir, Nasıl Çözülür?

Yayın tarihi:

13 dk okuma

Acar Diveroli
Yazar: Acar Diveroli
İz istemciden mavi proxy kutusuna ulaşıyor, soluk hedefe giden tünel kırmızı 403 ile kopuyor; alttaki şeritte RETRIES 0 var.

Fiyat takip betiğiniz bütün gece sorunsuz çalıştı. Bu sabah yeni paketinizin proxy adresini betiğe yapıştırdınız ve terminal artık tek bir uzun satır basıyor: HTTPSConnectionPool(host='example.com', port=443): Max retries exceeded with url. Betikte yeniden deneme ayarı yok, mesajdaki host da veri topladığınız mağaza; bu yüzden gözünüz hemen mağazaya gidiyor. Oysa satırın en sonunda, parantez içinde Tunnel connection failed: 403 Forbidden yazıyor ve bu cevabı mağaza değil, proxy vermiş.

Bu yazıda mesajı parçalarına ayırıyor ve hiç ayarlamadığınız hâlde neden "max retries" dediğini anlatıyoruz. Ardından kendi ürettiğimiz hata dizgilerinden hazırladığımız okuma tablosu, proxy'ye özgü türevler, zaman aşımları ve aynı hatanın pip'teki hâli geliyor. Sonda nedeni adıyla söyleyen, denenmiş bir Python betiği var.

"Max retries exceeded with url" ne anlama gelir?

Mesajı urllib3 üretir; Requests bağlantıları bu kütüphane üzerinden açar. urllib3 bir istekten vazgeçtiğinde MaxRetryError fırlatır. Requests bu hatayı yakalar ve içteki nedene göre seçtiği kendi istisnasını (exception) fırlatır: ConnectTimeout, ProxyError, SSLError, durum koduna göre yeniden denemeler tükendiğinde RetryError, geri kalan her durumda düz ConnectionError. Test çalıştırmamızdan aldığımız bir dizgiyi dört parçasına ayırdık:

text
requests.exceptions.ProxyError                        <- 1. Requests istisnası
HTTPSConnectionPool(host='example.com', port=443):    <- 2. havuz: hedef host ve port
Max retries exceeded with url: /                      <- 3. saran metin ve yol
(Caused by ProxyError('Unable to connect to proxy',   <- 4. asıl neden, dıştan içe
    OSError('Tunnel connection failed: 403 Forbidden')))

Çoğu kişi 2. parçada yanılır. Bir https:// URL'sinde havuz satırı, istek proxy üzerinden gitse bile hedefi gösterir; proxy adresi yalnız 4. parçada geçer, o da her zaman değil. Proxy üzerinden gönderilen düz bir http:// URL'de durum tersine döner: havuz satırı proxy'yi gösterir, hedefin tam URL'si de 3. parçada yer alır, örneğin HTTPConnectionPool(host='127.0.0.1', port=8083): Max retries exceeded with url: http://example.com/.

Hiç yeniden deneme ayarlamadığınız hâlde neden "max retries" yazıyor?

Requests başarısız bağlantıları varsayılan olarak yeniden denemez. requests/adapters.py kaynak kodunda DEFAULT_RETRIES = 0 tanımlıdır ve adaptör bunu Retry(0, read=False) nesnesine çevirir. urllib3 dokümantasyonu Retry sınıfı için, yeniden denemeler retries=False ile kapatılmadıkça hataların MaxRetryError içine sarıldığını söyler. Sıfır yeniden deneme "kapalı" sayılmaz; bu yüzden tek bir başarısız deneme bile "Max retries exceeded" diye çıkar.

Yeniden deneme sayısını artırmak nedeni ortadan kaldırmaz. Yanlış yazılmış bir proxy adı, yanlış port ya da reddedilen bir tünel her seferinde aynı şekilde düşer. Testimizde bağlantı zaman aşımı 2 saniye olan ulaşılamaz bir adres, varsayılan ayarla 2 saniyede, iki yeniden deneme ve kısa bir beklemeyle (backoff) 7 saniyede hata verdi. Yeniden deneme yalnız kısa ağ kopmalarında işe yarar.

Hata mesajı adım adım nasıl okunur?

Mesajı dıştan içe doğru okuyun:

  1. Requests istisnasını bulun. ProxyError, hatanın proxy'ye giden yolda ya da proxy'nin kendisinde oluştuğunu söyler.
  2. Havuz satırını okuyun. https:// hedeflerde host ve port hedefe aittir. HTTP proxy üzerinden 443 portu görüyorsanız istek bir CONNECT tünelinden geçiyordur.
  3. Caused by sonrasındaki ilk sınıfı okuyun. Bu, urllib3'ün teşhisidir: NameResolutionError, NewConnectionError, ConnectTimeoutError, SSLError ya da ProxyError.
  4. En içteki metni okuyun. Failed to resolve 'name', Linux'ta [Errno 111] Connection refused, Windows'ta [WinError 10061], CERTIFICATE_VERIFY_FAILED ya da Tunnel connection failed: 403 Forbidden. Burada geçen bir host= proxy'ye ait olabilir.
  5. Çağrının ne kadar sürdüğüne bakın. Tam olarak bağlantı zaman aşımınız kadar (ya da onun katları kadar) süren bir hata zaman aşımıdır; daha çabuk düşen bir hata ise bağlantı reddi ya da reddedilen bir tüneldir. Testlerimizde Windows'ta reddedilen bir bağlantı adres başına yaklaşık iki saniye, localhost ise dört saniye sürdü (önce IPv6, sonra IPv4).

HTTPSConnectionPool hataları: Caused by kısmı ne söyler?

Aşağıdaki dizgilerin hepsini Python 3.13, Requests 2.34.2 ve urllib3 2.8.0 ile, yerel bir test proxy'si üzerinden kendimiz ürettik. Uzun kısımlar ... ile kısaltıldı; Windows hata metni ayrıca sistem diline göre değişir.

Caused by (en içteki kısım)Requests istisnasıNe olduÖnce kontrol edin
NameResolutionError(... Failed to resolve 'no-such-host.invalid' ...)ConnectionErrorHedef adı çözülemediURL yazımı, DNS, VPN
NewConnectionError(... [Errno 111] or [WinError 10061] ...)ConnectionErrorO portu dinleyen bir şey yokServis çalışıyor mu, port doğru mu
ConnectTimeoutError(... 'Connection to 10.255.255.1 timed out. (connect timeout=2)')ConnectTimeoutSüre içinde TCP bağlantısı kurulamadıAdres, güvenlik duvarı, zaman aşımı değeri
SSLError(SSLCertVerificationError(... CERTIFICATE_VERIFY_FAILED ...))SSLErrorSertifikaya güvenilmiyorcertifi, kurumsal kök sertifika
ProxyError('Unable to connect to proxy', NewConnectionError(...))ProxyErrorProxy portu bağlantıyı reddettiProxy host ve portu, yerel güvenlik duvarı
ProxyError('Unable to connect to proxy', NameResolutionError(... 'pr.proxynet.invalid' ...))ProxyErrorProxy adı çözülemediProxy host'unda yazım hatası
ProxyError('Unable to connect to proxy', ConnectTimeoutError(...))ProxyErrorProxy zamanında cevap vermediProxy adresi, o port için giden bağlantı kuralları
ProxyError(..., OSError('Tunnel connection failed: 403 Forbidden'))ProxyErrorProxy CONNECT tünelini reddettiHedef port, proxy türü ve portu, izin kuralları
ProxyError(..., OSError('Tunnel connection failed: 407 Proxy Authentication Required'))ProxyErrorProxy geçerli kimlik bilgisi istiyorBkz. Proxy Kimlik Doğrulama
ProxyError(..., OSError('Tunnel connection failed: 502 Bad Gateway'))ProxyErrorProxy hedefe ulaşamadıHedef host ve port
ProxyError('... Your proxy appears to only use HTTP and not HTTPS ...', SSLError(... WRONG_VERSION_NUMBER ...))ProxyErrorProxy URL'si https:// ile başlıyorhttp:// yazın

Tabloya girmeyen üç ayrıntı var. Zaman aşımına uğrayan bir proxy ProxyError fırlatır; yani except ConnectTimeout onu hiç yakalamaz. Okuma zaman aşımı sarılmaz: Read timed out. (read timeout=3) metniyle ReadTimeout olarak gelir. Proxy üzerinden gönderilen düz bir http:// URL'de şifre yanlışsa da hiçbir istisna oluşmaz; 407 durum kodlu bir yanıt alırsınız.

"ProxyError: Cannot connect to proxy" ne anlama gelir?

Cannot connect to proxy. (urllib3 1.26) ile Unable to connect to proxy (urllib3 2.x) aynı hatadır. İkisi aynı makinede de görülebilir: pip 25.x kendi içinde urllib3 1.26.20 taşır, sıfırdan kurulan Requests ise urllib3 2.8.0'ı çeker. İfadeye değil, ikinci argümana bakın:

  • NewConnectionError: o proxy portunu dinleyen bir şey yok ya da yerel bir güvenlik duvarı engelliyor. Host ve portu panelden yeniden kopyalayın.
  • NameResolutionError: proxy host adı yanlış yazılmış ya da DNS'iniz bu adı çözemiyor.
  • ConnectionResetError (Linux'ta Errno 104, Windows'ta WinError 10054): proxy ya da yoldaki bir cihaz bağlantıyı kapattı.
  • OSError('Tunnel connection failed: ...'): proxy cevap verdi ama tüneli açmadı; durum kodu onun cevabıdır.

Tarayıcıdaki karşılığı olan "Proxy sunucusu yanıt vermiyor" hatası için Proxy Hatası Nedir? yazımıza bakın.

Tunnel connection failed: 403 Forbidden: proxy CONNECT'i neden reddeder?

HTTP proxy üzerinden giden bir https:// isteği CONNECT example.com:443 ile başlar. Proxy hedefe bir TCP bağlantısı açar ve şifreli baytları iki yana aktarır; sayfanın içeriğini hiç görmez. RFC 9110'un 9.3.6 bölümüne göre 2xx dışındaki her cevap, tünelin kurulmadığı anlamına gelir. Python'un http.client modülü bu cevabı okur ve Tunnel connection failed yazar.

403 proxy'nin kararıdır; hedef site isteğinizi hiç görmedi. RFC, proxy'lerin CONNECT'i bilinen portlarla ya da güvenli hedeflerden oluşan bir listeyle sınırlaması gerektiğini söyler, çünkü 25 portuna açılan bir tünel spam aktarmak için kullanılabilir. Sık görülen nedenler:

  • Hedef portuna izin yok. https://example.com:8443/ başarısız olurken https://example.com/ çalışabilir.
  • İzin listesi. Kurumsal proxy'ler ve bazı barındırma platformları yalnız onaylı alan adlarına izin verir. BT ekibine sorun ya da platformun dokümantasyonunu okuyun; politikayı aşmaya çalışmayın.
  • Yanlış proxy türü ya da port, örneğin başka bir protokol için ayrılmış bir port.
  • Sağlayıcı kuralları. Bir sağlayıcı bazı hedeflere tünel açmayı reddedebilir; hangi durum kodlarını kullandığı dokümantasyonunda yazar.

Hedef siteden gelen 403 ise sayfasıyla birlikte normal bir yanıt olarak gelir; bu durumu Scraping'de HTTP Hata Kodları yazısında anlattık. Tünelde 407 görürseniz proxy kimlik bilgisi istiyor demektir.

Proxy URL'si http:// ile mi, https:// ile mi başlamalı?

proxies sözlüğünde anahtar hedefin şemasıdır, değer ise proxy'ye nasıl ulaşılacağıdır. Requests dokümantasyonunun kendi örneği 'https' anahtarını 'http://10.10.1.10:1080' değerine bağlar. Çoğu proxy düz HTTP konuşur ve şifreli siteler için bir CONNECT tüneli açar (HTTPS proxy sayfamıza bakın); bu yüzden iki anahtarın değeri de http:// ile başlar:

python
proxies = {
    "http": "http://user:pass@pr.proxynet.io:8000",
    "https": "http://user:pass@pr.proxynet.io:8000",  # burada da http://
}

Değerde https:// varsa urllib3 2.x proxy'nin kendisiyle TLS bağlantısı kurmaya çalışır, düz bir HTTP proxy TLS olmayan baytlarla cevap verir ve Your proxy appears to only use HTTP and not HTTPS ipucuyla birlikte WRONG_VERSION_NUMBER hatası alırsınız. urllib3'ün bu hatayı anlatan sayfası aynı çözümü verir; yanlış yazılmış bir HTTPS_PROXY değişkeni için de geçerlidir.

İlgili iki nokta:

Timeout vermezseniz ne olur? ConnectTimeout ve ReadTimeout farkı

Requests'in varsayılan bir zaman aşımı yoktur: timeout= vermezseniz bir çağrı dakikalarca asılı kalabilir ve size okuyacak bir hata bile bırakmaz. timeout=(3.05, 20) gibi bir tuple verin: önce bağlantı, sonra okuma zaman aşımı, saniye cinsinden. Dokümantasyon, bağlantı zaman aşımını 3'ün bir katının biraz üstüne koymayı önerir; 3 saniye, TCP'nin varsayılan yeniden iletim penceresidir.

İki zaman aşımı farklı şekilde düşer:

  • ConnectTimeout: süre içinde TCP bağlantısı kurulamadı. "Max retries exceeded" içine sarılı gelir ve API referansı bu hatayı yeniden denemesi güvenli sayar.
  • ReadTimeout: bağlantı kuruldu ama okuma zaman aşımı içinde veri gelmedi. Sarılmaz; sunucu isteği çoktan işlemiş olabilir, bu yüzden bir POST'u yeniden denemek aynı işi iki kez yaptırabilir.

Bağlantı zaman aşımı her IP adresi için ayrı işler; hem IPv4 hem IPv6 adresi olan bir adda bekleme iki katına çıkabilir. Okuma zaman aşımı iki bayt arasındaki boşluğa konan sınırdır, indirmenin tamamına değil. Diğer kütüphanelerin varsayılanlarını HTTPX, Requests ve AIOHTTP Karşılaştırması yazısında bulabilirsiniz.

Aynı hata pip'te: "Retrying ... after connection broken by"

pip kendi Requests ve urllib3 kopyalarını taşır, bu yüzden pip install aynı nedenlerle düşer. pip dokümantasyonu varsayılanları --retries 5 ve --timeout 15 saniye olarak verir. pip 26.2.1'i --retries 2 ile, her CONNECT'i 403 ile reddeden yerel bir proxy üzerinden çalıştırdık:

text
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'OSError('Tunnel connection failed: 403 Forbidden')': /simple/six/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'OSError('Tunnel connection failed: 403 Forbidden')': /simple/six/
ERROR: Could not find a version that satisfies the requirement six (from versions: none)
ERROR: No matching distribution found for six

Paket var; pip paket dizinine hiç ulaşamadı. Neden WARNING satırlarında yazıyor. pip 25.2 aynı uyarıyı urllib3 1.26'nın ifadesiyle bastı: ProxyError('Cannot connect to proxy.', ...).

TLS trafiğini inceleyen bir kurumsal proxy arkasında CERTIFICATE_VERIFY_FAILED alıyorsanız kurumun kök sertifikasını --cert ile verin; --trusted-host doğrulamayı kapatır ve son çaredir. pip'e proxy tanıtmayı Linux Proxy Ayarları yazısında anlattık.

Nedeni söyleyen bir Python betiği

Betik bir istisnayı tek satıra çevirir: neyin düştüğünü ve neyin kontrol edileceğini söyler. Şunları yapar:

  • yalnız başarısız bağlantıları, iki kez yeniden dener;
  • read=False ayarını korur: testimizde read=0, bir ReadTimeout hatasını sarılmış bir ConnectionError'a çevirdi;
  • other=0 ayarlar: bu ayar olmadan 403 ya da 407 ile reddedilen bir tünel üç kez denendi;
  • her istekte proxies= ve timeout=(3.05, 20) verir;
  • ProxyError, SSLError ve ConnectTimeout istisnalarını, üst sınıfları olan ConnectionError'dan önce yakalar.

Durum koduna göre yeniden deneme ayrı bir katmandır (Scraping'de HTTP Hata Kodları), proxy döndürme de öyle (Python'da Proxy'ler Nasıl Döndürülür?).

python
"""Max retries exceeded with url hatasının arkasındaki asıl nedeni bulur ve neye bakılacağını söyler."""
import re
import ssl
import time

import requests
from requests.adapters import HTTPAdapter
from urllib3.exceptions import (
    ConnectTimeoutError,
    NameResolutionError,
    NewConnectionError,
    ProxyError as Urllib3ProxyError,
)
from urllib3.util import Retry

PROXY = "http://user:pass@pr.proxynet.io:8000"  # https:// hedeflerde de http://
TIMEOUT = (3.05, 20)  # saniye: (bağlantı, okuma)


def make_session():
    """Başarısız bağlantıları iki kez yeniden deneyen, başka hiçbir şeyi denemeyen bir oturum."""
    retry = Retry(
        total=2,
        connect=2,      # DNS hataları, reddedilen ve zaman aşımına uğrayan bağlantılar
        read=False,     # ReadTimeout, ReadTimeout olarak kalsın: istek sunucuya ulaşmış olabilir
        other=0,        # tüneli reddeden proxy onu yine reddeder
        status=0,       # durum koduna göre yeniden deneme başka bir katmanın işi
        backoff_factor=0.5,
    )
    adapter = HTTPAdapter(max_retries=retry)
    session = requests.Session()
    session.mount("http://", adapter)
    session.mount("https://", adapter)
    return session


def causes(exc):
    """İstisnanın kendisi ve içine sarılmış her hata, dıştan içe."""
    chain = []
    while exc is not None and all(exc is not seen for seen in chain):
        chain.append(exc)
        inner = None
        for candidate in (getattr(exc, "reason", None), getattr(exc, "original_error", None),
                          exc.__cause__, exc.__context__, *exc.args[:2]):
            if isinstance(candidate, BaseException):
                inner = candidate
                break
        exc = inner
    return chain


def explain(exc):
    """Tek satır: ne düştü, hangi tarafta ve önce neye bakılmalı."""
    chain = causes(exc)
    text = " | ".join(str(e) for e in chain)
    side = "proxy" if any(isinstance(e, Urllib3ProxyError) for e in chain) else "target"

    tunnel = re.search(r"Tunnel connection failed: (\d{3})", text)
    if tunnel:
        code = tunnel.group(1)
        if code == "407":
            return "proxy asked for credentials (407): check user:pass or the IP whitelist"
        if code == "403":
            return "proxy refused the CONNECT tunnel (403): check the target port and the proxy's allow rules"
        return f"proxy was reached but could not reach the target ({code}): check the target host and port"
    if "appears to only use HTTP" in text:
        return "proxy URL starts with https:// but the proxy speaks plain HTTP: write http://"
    if any(isinstance(e, NameResolutionError) for e in chain):
        host = re.search(r"Failed to resolve '([^']+)'", text)
        return f"{side} name {host.group(1) if host else ''} does not resolve: check spelling, DNS and VPN"
    if any(isinstance(e, ssl.SSLCertVerificationError) for e in chain):
        return "certificate not trusted: update certifi or set REQUESTS_CA_BUNDLE to your company root CA"
    if isinstance(exc, requests.exceptions.ReadTimeout):
        return "connected, but no answer within the read timeout: the server may have the request"
    if any(isinstance(e, NewConnectionError) for e in chain):
        return f"{side} refused the connection: wrong port, service down, or a firewall rejects it"
    if any(isinstance(e, ConnectTimeoutError) for e in chain):
        return f"no TCP connection to the {side} within the connect timeout: check address, port, firewall"
    return f"unrecognised, read the innermost error: {chain[-1]!r}"


def fetch(session, url, proxy=PROXY):
    """Tek bir URL'ye GET atar; durumu ya da istek düştüyse teşhisi yazdırır."""
    proxies = {"http": proxy, "https": proxy} if proxy else None  # istek başına: ortam değişkenleri bunu ezemez
    start = time.monotonic()
    try:
        resp = session.get(url, proxies=proxies, timeout=TIMEOUT)
    except requests.exceptions.ProxyError as exc:      # ConnectionError'dan önce: onun alt sınıfı
        kind, error = "ProxyError", exc
    except requests.exceptions.SSLError as exc:        # bu da bir ConnectionError
        kind, error = "SSLError", exc
    except requests.exceptions.ConnectTimeout as exc:  # aynı anda hem ConnectionError hem Timeout
        kind, error = "ConnectTimeout", exc
    except requests.exceptions.ReadTimeout as exc:     # asla "Max retries exceeded" içine sarılmaz
        kind, error = "ReadTimeout", exc
    except requests.exceptions.ConnectionError as exc:
        kind, error = "ConnectionError", exc
    else:
        print(f"{'OK':<16}{time.monotonic() - start:6.2f}s  {url}  HTTP {resp.status_code}")
        return resp
    print(f"{kind:<16}{time.monotonic() - start:6.2f}s  {url}\n{'':<24}{explain(error)}")
    return None


if __name__ == "__main__":
    session = make_session()
    for url in ["https://httpbin.org/ip", "https://example.com/"]:
        fetch(session, url)

urllib3 2.x'te NameResolutionError, NewConnectionError sınıfının alt sınıfıdır; o da ConnectTimeoutError sınıfının alt sınıfıdır. Bu yüzden explain() önce en özel sınıfı sınar. Betik için pip install requests yeterli.

Çıktı nasıl görünüyor?

fetch() fonksiyonunu Windows 11'de her durum için bir kez çalıştırdık: yerel bir test proxy'si (doğru ve yanlış şifre, kapalı port, yanlış yazılmış ad, https:// şeması), her CONNECT'i reddeden ikinci bir proxy, sertifika ve zaman aşımı durumları için de gerçek host'lar. Okuma zaman aşımı 5 saniyeydi:

text
OK                0.77s  https://httpbin.org/ip  HTTP 200
ProxyError        0.02s  https://httpbin.org/ip
                        proxy asked for credentials (407): check user:pass or the IP whitelist
ProxyError        0.00s  https://example.com/
                        proxy refused the CONNECT tunnel (403): check the target port and the proxy's allow rules
ProxyError        0.02s  https://no-such-host.invalid/
                        proxy was reached but could not reach the target (502): check the target host and port
ProxyError        7.10s  https://httpbin.org/ip
                        proxy refused the connection: wrong port, service down, or a firewall rejects it
ProxyError        1.02s  https://httpbin.org/ip
                        proxy name pr.proxynet.invalid does not resolve: check spelling, DNS and VPN
ProxyError        0.21s  https://httpbin.org/ip
                        proxy URL starts with https:// but the proxy speaks plain HTTP: write http://
SSLError          0.63s  https://self-signed.badssl.com/
                        certificate not trusted: update certifi or set REQUESTS_CA_BUNDLE to your company root CA
ConnectTimeout   10.16s  http://10.255.255.1/
                        no TCP connection to the target within the connect timeout: check address, port, firewall
ReadTimeout       5.02s  http://127.0.0.1:8082/
                        connected, but no answer within the read timeout: the server may have the request
ConnectionError  13.12s  http://localhost:8083/
                        target refused the connection: wrong port, service down, or a firewall rejects it

Reddedilen tüneller milisaniyeler içinde düştü, çünkü other=0 onları durdurdu. Kapalı proxy portunda süre, yaklaşık ikişer saniyelik üç deneme ile bir saniyelik beklemeden oluştu; bağlantı zaman aşımında ise üç kez 3,05 saniye ile beklemeden. localhost 13 saniye sürdü, çünkü her deneme önce IPv6'yı, sonra IPv4'ü denedi. 502 ise hedefi çözemeyen test proxy'mizden geldi.

Bu hatayla nerelerde karşılaşırsınız?

  • Proxy üzerinden web scraping (veri kazıma): sitelerden otomatik veri toplarken proxy hataları, herhangi bir durum kodu görmeden önce bu mesajla karşınıza çıkar (proxy üzerinden veri toplama).
  • Kurumsal proxy arkasında CI ve Docker derlemeleri: derlemeler çoğu zaman makinenin proxy ayarlarını almaz, localhost da konteynerin kendisidir (Linux Proxy Ayarları).
  • Sabit çıkış IP'siyle çalışan API entegrasyonları: reddedilen bir tünel API kesintisi gibi görünür (API için Statik IP).
  • Yeni bir proxy'yi denemek: bütün işi başlatmadan önce zaman aşımı verilmiş tek bir istek gönderin (Proxy Nasıl Test Edilir?).
  • Tarayıcı otomasyonu: aynı tünel hatası ERR_TUNNEL_CONNECTION_FAILED olarak görünür (Playwright ile proxy kullanımı).
  • Kurumsal ağlar: bağlantıları hem güvenlik duvarı hem proxy süzer (Proxy ve Firewall Farkı).

Sık yapılan hatalar

  • Yeniden deneme sayısını artırmak. Kalıcı bir neden kalıcı kalır; yalnız daha uzun beklersiniz.
  • Adı havuz satırında geçtiği için hedefi suçlamak. https:// URL'lerde proxy yalnız parantez içinde görünür.
  • Eski bir HTTPS_PROXY değişkenini unutmak. session.proxies ayarının yerine sessizce geçebilir.
  • Canlı ortamda verify=False bırakmak. Requests dokümantasyonu bu ayarın sizi ortadaki adam (man-in-the-middle) saldırılarına açık bıraktığını söyler. certifi'yi güncelleyin ya da REQUESTS_CA_BUNDLE ayarlayın; yerel bir hata ayıklama proxy'si için MITM Proxy yazısına bakın.
  • Önce ConnectionError yakalamak. ProxyError, SSLError ve ConnectTimeout hatalarını yutar.
  • Tünel 403'ünü 407 ile karıştırmak. Biri kural, diğeri kimlik bilgisi sorunudur.
  • pip'te yalnız son satırı okumak. Neden, onun üstündeki WARNING satırlarındadır.

Karar rehberi

Ne görüyorsunuzNe yapmalı
Caused by içinde NameResolutionErrorÇözülemeyen adı düzeltin (proxy host'u ya da URL); yeniden deneme eklemeyin
NewConnectionError ile gelen ProxyErrorProxy host ve portunu yeniden kopyalayın; yerel güvenlik duvarını kontrol edin
Tunnel connection failed: 403Hedef portu, proxy türünü ve portunu, izin kurallarını kontrol edin
Tunnel connection failed: 407Kimlik bilgilerini ya da IP whitelist'i kontrol edin
SSLError: CERTIFICATE_VERIFY_FAILEDcertifi'yi güncelleyin ya da REQUESTS_CA_BUNDLE ayarlayın (pip: --cert)
Çağrılar ara sıra asılı kalıyor ya da zaman aşımına uğruyortimeout=(3.05, 20) ve yalnız bağlantı hatalarını deneyen bir Retry
pip "No matching distribution found" diyorWARNING: Retrying satırını okuyun

Sıkça sorulan sorular

Yeniden deneme sayısını artırmak "Max retries exceeded" hatasını çözer mi?

Yalnız ağ bir anlığına koptuğunda. Çözülemeyen bir ad, kapalı bir port ya da reddedilen bir tünelde her yeniden deneme aynı şekilde düşer. Önce Caused by kısmını okuyun.

Python Requests'te varsayılan timeout nedir?

Yoktur: timeout= vermezseniz bir istek süresiz bekleyebilir. Her çağrıya bir (bağlantı, okuma) tuple'ı verin.

Requests'te timeout saniye mi, milisaniye mi?

Saniye. 3.05 gibi ondalıklı bir değer de çalışır; tek bir sayı iki aşamayı birlikte ayarlar, (3.05, 20) gibi bir tuple ise ikisini ayrı ayrı.

CERTIFICATE_VERIFY_FAILED için verify=False kullanabilir miyim?

Yalnız kısa bir yerel denemede, çünkü bu ayar yoldaki herkesin trafiği okumasına ya da değiştirmesine izin verir. Kalıcı çözüm güncel bir certifi ya da, TLS'i inceleyen bir kurumsal proxy arkasındaysanız, o proxy'nin kök sertifikasını REQUESTS_CA_BUNDLE ile göstermektir.

Paket var, pip neden "No matching distribution found" diyor?

pip paket dizinine ulaşamadı, bu yüzden hiçbir sürüm bulamadı. Üstteki WARNING: Retrying ... after connection broken by satırları asıl nedeni söyler, örneğin Tunnel connection failed: 403 Forbidden.

localhost:8000'e istek atarken neden bu hatayı alıyorum?

O portu dinleyen bir şey yok: sunucu kapalı, başka bir port kullanıyor ya da kodunuz Docker içinde çalışıyor ve orada localhost konteynerin kendisi; en içteki hata [Errno 111] ya da [WinError 10061] olur. Portu hangi programın tuttuğunu bulmayı 8080 portu yazımızda anlattık.

Özet

"Max retries exceeded with url" asıl hatayı saran bir mesajdır: neden Caused by sonrasında yazar ve Requests varsayılan olarak yeniden deneme yapmadığı için mesaj tek denemeden sonra da çıkar. Proxy hatalarında proxy'ye giden yoldaki bir sorunu proxy'nin reddettiği bir tünelden ayırın ve proxy URL'sinde http:// kullanın. Her isteğe bir zaman aşımı tuple'ı verin ve yalnız bağlantı hatalarını yeniden deneyin. Yeni bir kurulumu önce tek bir istekle deneyin (proxy nasıl test edilir), seçenekleri de proxy hizmetlerimiz sayfasında karşılaştırın.

ChatGPT'ye sorClaude'a sor