Geonode logo
Geonode Team

Geonode Team

Mis à jour : 7 octobre 2026

Publié : 2 septembre 2026

Comment définir un délai d'expiration avec curl (+ exemples)

Par défaut, curl attend indéfiniment. Il n'y a pas de limite de temps globale intégrée ; ainsi, une requête adressée à un hôte qui ne répond pas peut rester bloquée jusqu'à ce qu'un autre processus la force à s'arrêter. Deux options permettent de remédier à cela, et une troisième couvre le cas que ces deux-là ne prennent pas en compte. Ce guide aborde ces trois options à l'aide de commandes fonctionnelles. Il traite également de l'interaction entre les délais d'expiration et les tentatives de réessai, ce qui surprend presque tout le monde la première fois qu'un script met dix minutes à échouer.

Une petite précision avant de passer aux commandes : nous sommes Geonode et nous vendons des proxys ; il est donc honnête de préciser d’emblée qu’un délai d’expiration de curl n’est presque jamais dû à un problème de proxy. Si vos requêtes expirent face à un serveur simplement lent, à un hébergeur hors service ou à un pare-feu qui rejette les paquets sans le signaler, les acheminer via nos serveurs ne changera rien, si ce n’est le montant de la facture. Les proxys sont utiles lorsque le problème réside dans l’origine apparente de votre requête : contenu soumis à des restrictions géographiques, limites de débit liées à votre adresse, ou encore une adresse IP bloquée. Ils ne transforment pas un serveur lent en serveur rapide. Commencez par régler correctement vos délais d’expiration ; vous constaterez peut-être que vous n’aviez besoin de rien d’autre.

Exact. Voici ce que la plupart des gens découvrent à leurs dépens : curl n’a pas de délai d’expiration global par défaut. Il dispose d’un délai d’expiration de connexion par défaut de 300 secondes, mais une fois la connexion établie, curl attendra joyeusement indéfiniment une réponse qui n’arrivera jamais complètement. Dans un script shell s’exécutant via cron, cela se traduit par une tâche qui ne se termine jamais et un fichier de verrouillage que personne ne libère.

Les deux délais d'attente qui comptent

Tout le reste n'est qu'un approfondissement de ces deux éléments.

--max-time

(forme abrégée : -m

) encadre l'ensemble de l'opération. D'après le manuel de curl : « Durée maximale, en secondes, que vous autorisez pour l'opération de transfert. » Connexion, établissement de la connexion, requête, réponse, tout y passe. Lorsque la limite est atteinte, curl interrompt l’opération et se termine avec le code 28.

curl -m 10 https://example.com

Dix secondes au total, puis curl abandonne quelle que soit l’étape atteinte.

--connect-timeout

ne limite que la phase d’établissement de la connexion. Le manuel précise clairement ce que cela inclut : « La phase de connexion est considérée comme terminée lorsque la recherche DNS et les handshakes TCP, TLS ou QUIC demandés sont effectués. » Une fois la connexion établie, cette option ne s’applique plus.

curl --connect-timeout 3 https://example.com

Trois secondes pour résoudre le nom et terminer les handshakes. Après cela, curl attend le temps nécessaire au transfert.

En pratique, les deux options sont utiles, car elles répondent à des questions différentes :

OptionCouvreValeur typiqueContre quoi protège-t-elle ?
--connect-timeout

| Poignée de main DNS + TCP/TLS/QUIC | 3 à 10 s | Hôtes inactifs, paquets perdus, défaillances DNS | | --max-time

| L’opération dans son ensemble | 10 à 60 s, en fonction de la charge de travail | Réponses lentes, transferts bloqués, flux interminables |

Au total :

curl --connect-timeout 5 -m 30 https://example.com

Cinq secondes pour établir la connexion, trente secondes pour l’ensemble du processus. Si l’hôte est inaccessible, l’échec survient au bout de cinq secondes plutôt que de trente, ce qui a une grande importance lorsque l’on parcourt une liste de mille URL.

Choisir des valeurs qui ne sont pas des approximations

L'approche habituelle consiste à choisir un chiffre rond et à l'ajuster à la hausse chaque fois qu'une opération échoue. Cela conduit à une valeur suffisamment élevée pour que le délai d'expiration ne serve plus à rien.

Une meilleure méthode nécessite une commande supplémentaire. curl peut indiquer où le temps s'est réellement écoulé :

curl -o /dev/null -s -w "dns: %{time_namelookup}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n" https://example.com

Exécutez cette commande sur votre cible réelle vingt ou trente fois et vous obtiendrez une distribution plutôt qu’une estimation. Ensuite :

Définissez --connect-timeout à partir de time_appconnect. Prenez la valeur p95 et doublez-la approximativement. Le temps de connexion est principalement déterminé par les allers-retours réseau et est relativement stable ; s’il prend deux fois plus de temps que d’habitude, c’est qu’il y a véritablement un problème et non pas simplement un ralentissement.

Définissez --max-time à partir de time_total. Ici, le multiplicateur doit être plus généreux — trois à cinq fois le p95 — car le temps total dépend de la taille de la réponse et de la charge du serveur, deux facteurs qui varient légitimement. Une valeur trop stricte de --max-time produit des scripts instables qui échouent lors de simples jours difficiles.

Deux ajustements spécifiques à la charge de travail. Si vous téléchargez des fichiers volumineux, --max-time n’est absolument pas l’outil adapté, car un téléchargement légitime peut dépasser n’importe quelle limite fixe raisonnable — utilisez plutôt l’option basée sur la vitesse ci-dessous. Et si vous appelez une API qui effectue un véritable travail côté serveur, renseignez-vous sur son propre délai d’expiration et définissez le vôtre à une valeur légèrement supérieure ; un délai d’expiration de 10 secondes pour un service qui renvoie une réponse au bout de 12 secondes signifie que vous payez pour le travail effectué et que vous perdez le résultat.

Précision au centième de seconde et à la milliseconde

Ces deux options acceptent les nombres décimaux, en utilisant un point comme séparateur, quel que soit votre paramètre régional. Cette fonctionnalité est prise en charge depuis la version 7.32.0 de curl.

curl --connect-timeout 0.5 -m 2.5 https://example.com

Une demi-seconde pour se connecter, deux secondes et demie au total. Utile pour les contrôles d'intégrité et pour toute boucle où une seconde entière d'attente par échec finit par s'accumuler.

Une mise en garde à connaître : la précision diminue à mesure que la valeur augmente. La documentation de curl indique que le délai d’expiration réel perd en précision à mesure que la précision décimale du délai spécifié augmente. Écrire --max-time 30.001 n’apporte pas de différence significative par rapport à --max-time 30. Les décimales sont destinées aux valeurs inférieures à la seconde ; au-delà de quelques secondes, utilisez des nombres entiers.

L’option associée --expect100-timeout accepte également les décimales. Elle contrôle le temps pendant lequel curl attend une réponse « 100 Continue » avant d’envoyer le corps de la requête ; la valeur par défaut est d’une seconde. Si vous envoyez des corps de requête volumineux via POST à un serveur qui ne renvoie jamais de « 100 Continue », vous payez cette seconde à chaque requête — réduisez-la ou désactivez cette attente avec -H "Expect:".

Détection des transferts bloqués qui n'atteignent jamais le délai d'expiration

Voici le problème. Un transfert qui envoie un octet toutes les quelques secondes n'est jamais inactif ; par conséquent, aucun délai d'expiration au niveau de la connexion ne se déclenche, et si la valeur « --max-time

» est définie à un niveau suffisamment élevé pour les téléchargements volumineux légitimes, elle ne se déclenchera pas non plus. La requête avance tout simplement au ralenti.

Les options --speed-limit

et --speed-time

permettent de gérer ce cas. D’après le manuel : « Si un téléchargement est plus lent que --speed-limit

octets par seconde pendant une période de --speed-time

, le transfert est interrompu. »

curl --speed-limit 1000 --speed-time 30 -O https://example.com/large-file.zip

Si le débit reste inférieur à 1 000 octets par seconde pendant 30 secondes consécutives, curl interrompt le téléchargement — là encore avec le code de sortie 28. Un téléchargement qui s’effectue pendant six heures à un rythme satisfaisant n’est pas affecté. Un téléchargement qui stagne est interrompu au bout de trente secondes.

Il s’agit du délai d’expiration approprié pour tout élément de taille imprévisible, et il s’intègre bien :

curl --connect-timeout 5 --speed-limit 1000 --speed-time 30 -O https://example.com/large-file.zip

Échec rapide sur un hôte inactif, pas de limite globale, mais un détecteur de ralentissement permanent. Pour les téléchargements de fichiers en particulier, ce modèle a sa place dans chaque script — consultez notre guide sur le téléchargement de fichiers avec curl pour connaître les options associées.

Les délais d'expiration et les tentatives de réessai interagissent mal par défaut

C’est là que beaucoup se font piéger. L’option `

--retry N

fait quecurl réessaie jusqu’à N fois en cas d’erreurs transitoires. Ce qu’on oublie facilement, c’est que l’option ``--max-time

s’applique à *chaque tentative*, et non à la commande dans son ensemble, et quecurl` attend entre chaque tentative en appliquant un délai d’attente exponentiel commençant à une seconde et doublant à chaque fois.

Ainsi, ceci :

curl -m 10 --retry 5 https://example.com

peut légitimement prendre bien plus d’une minute : cinq tentatives pouvant durer jusqu’à dix secondes chacune, plus des délais d’attente de 1, 2, 4, 8 et 16 secondes. Si vous l’avez écrit en vous attendant à un plafond de dix secondes, vous vous êtes trompé d’un facteur six.

--retry-max-time

est la solution. Elle limite la durée totale consacrée aux tentatives :

curl -m 10 --retry 5 --retry-max-time 40 https://example.com

Désormais, curl cesse de lancer de nouvelles tentatives une fois que 40 secondes se sont écoulées. Notez bien la formulation : il ne lancera pas de nouvelle tentative après la limite, mais une tentative déjà en cours se poursuivra jusqu’à son propre --max-time

. Le pire cas réel correspond à --retry-max-time

plus un --max-time

.

--retry-delay

remplace le délai d’attente exponentiel par un délai fixe, ce qui rend la durée d’exécution totale prévisible :

curl -m 10 --retry 3 --retry-delay 2 --retry-max-time 40 https://example.com

Autre indicateur à connaître : par défaut, ``--retry`

ne se déclenche que dans un ensemble restreint de conditions transitoires. ``--retry-all-errors

` élargit considérablement ce champ — le manuel décrit cette option comme permettant de réessayer « toutes les erreurs transitoires, y compris les codes de réponse FTP 4xx et 5xx ». C’est vraiment utile dans les scripts fonctionnant sur des réseaux instables, mais vraiment dangereux face à une requête POST non idempotente. Réfléchissez bien avant de l’ajouter.

Délais d'expiration lorsque vous passez par un proxy

Ajoutez -x

et le comportement en matière de délai change, car il y a désormais deux connexions au lieu d'une seule : celle entre vous et le proxy, et celle entre le proxy et la cible.

curl -x http://user:pass@proxy.example.com:9000 --connect-timeout 10 -m 45 https://example.com

Trois éléments se comportent différemment par rapport au cas d'une connexion directe.

**--connect-timeout

mesure le temps de transit entre vous et le proxy, et non celui entre le proxy et la cible.** Pour le HTTPS, curl envoie une requête « CONNECT

» et le proxy établit la connexion vers la cible ; le temps nécessaire à cette opération est comptabilisé dans « --max-time

», et non dans « --connect-timeout

». Un délai d’expiration de connexion court ne vous protégera donc pas contre un proxy qui accepte votre connexion rapidement, mais met ensuite vingt secondes pour atteindre la cible.

Les proxys résidentiels sont plus lents, et ce à juste titre. Le trafic transite par une véritable connexion grand public ; un surcroît de quelques centaines de millisecondes est donc normal et ne constitue pas un dysfonctionnement. Des valeurs de délai d’expiration réglées pour une connexion directe entraîneront des échecs qui ressembleront à des proxys défaillants, alors qu’il s’agit en réalité d’un phénomène physique. Effectuez des mesures via le proxy à l’aide de la commande -w

ci-dessus et définissez les valeurs à partir de ces mesures, et non à partir de vos chiffres de connexion directe.

Les échecs sont ambigus. Un code de sortie 28 via un proxy peut signifier que le proxy est lent, que la cible est lente ou que la cible bloque délibérément votre requête. Pour les distinguer, il faut tester les composants séparément, ce qui constitue un sujet suffisamment vaste pour que nous ayons rédigé un guide dédié au test des proxys.

Une approche pratique pour les requêtes via un proxy : un délai d’--connect-timeout

généreux (10 s), un délai d’--max-time

défini en fonction du comportement mesuré plutôt que d’une simple hypothèse, et pas de --retry-all-errors

, car via un proxy, un code 5xx signifie souvent que la cible vous refuse l’accès plutôt qu’elle traverse un moment difficile, et une nouvelle tentative ne ferait qu’empirer la situation.

Interprétation du code de sortie

Le code de sortie de curl vous indique à quelle étape l'échec s'est produit, ce qui représente davantage d'informations que la plupart des scripts ne prennent la peine d'exploiter.

CodeNomSignification
6CURLE_COULDNT_RESOLVE_HOSTÉchec DNS — aucun délai d'attente
7CURLE_COULDNT_CONNECT« Échec de la fonction connect() vers l’hôte ou le proxy »
28CURLE_OPERATION_TIMEDOUT« Le délai d’expiration spécifié a été atteint »
56CURLE_RECV_ERRORÉchec de la réception des données réseau — connexion interrompue en cours de transfert

Les descriptions sont tirées de la référence des erreurs libcurl.

La distinction entre les codes 7 et 28 est utile. Le code 7 signifie que la connexion a été activement refusée — une réponse a été renvoyée rapidement pour indiquer « non ». Le code 28 signifie qu’aucune réponse n’a été reçue à temps. Le premier indique généralement un port incorrect ou un service fermé ; le second indique un paquet perdu, un pare-feu filtrant silencieusement ou un hôte véritablement surchargé. Il est raisonnable de réessayer en cas de code 28, mais cela est généralement inutile pour le code 7.

Dans un script :

curl --connect-timeout 5 -m 30 -sS https://example.com > out.txt
case $? in
  0)  echo "ok" ;;
  6)  echo "dns failure" ;;
  7)  echo "connection refused" ;;
  28) echo "timed out" ;;
  *)  echo "other failure" ;;
esac

Notez que les trois mécanismes de délai d’expiration — --max-time, --connect-timeout et la paire de limites de vitesse — renvoient le code 28. Le code de sortie indique qu’une limite a été atteinte, sans préciser laquelle. Si vous avez besoin de le savoir, utilisez -w "%{time_total}" et comparez les résultats avec vos valeurs configurées.

Quand ne pas définir de délai d'expiration

Contrairement à ce que l'on conseille généralement, il existe des cas où un délai d'expiration n'est pas la bonne solution.

Téléchargements interactifs. Si vous saisissez une commande curl dans un terminal pour récupérer un fichier volumineux, c'est vous qui fixez le délai d'expiration. Vous pouvez voir la barre de progression et appuyer sur Ctrl-C. Ajouter -m dans ce cas ne fait qu’entraîner la frustration d’un téléchargement qui s’interrompt à 90 %.

Flux de longue durée. Événements envoyés par le serveur, suivi de journaux, réponses fragmentées qui restent ouvertes par conception — --max-time mettra fin à ces flux exactement au mauvais moment. Utilisez --speed-limit et --speed-time si vous avez besoin d’un détecteur de blocage, ou rien du tout.

Tout ce qui est déjà soumis à une limite externe. Si curl s’exécute sous timeout(1), une unité systemd avec RuntimeMaxSec, ou une étape de CI disposant de son propre budget, une deuxième couche n’apporte rien d’autre qu’un deuxième chiffre à synchroniser. Choisissez la couche qui génère le message d’erreur que vous souhaitez lire et configurez-la à cet endroit.

Pour remédier à une cible lente. Un délai d’expiration fait échouer plus rapidement une requête lente. Il ne la fait pas aboutir. Si votre véritable problème est qu’un serveur met 40 secondes à répondre, les options sont la mise en cache, la pagination, un point de terminaison différent ou une discussion avec la personne qui le gère — et c’est là que nous allons répéter la mise en garde du début, car c’est le problème le plus courant pour lequel les gens achètent des proxys et l’un des rares problèmes que les proxys ne peuvent absolument pas résoudre. Nos tarifs commencent à 0,79 $/Go pour le trafic résidentiel et à 0,14 $/Go pour le trafic de centre de données, selon les informations disponibles en septembre 2026, et aucun d’entre eux ne permettra d’accélérer un serveur d’origine lent.

Questions fréquentes

Quel est le délai d’expiration par défaut dans curl ?

Il n’y a pas de délai d’expiration global par défaut : une fois connecté, curl attend indéfiniment une réponse. La phase de connexion a toutefois un délai par défaut de 300 secondes. C’est pourquoi l’option -m est importante dans les scripts : sans elle, une requête bloquée bloque le script.

Quelle est la différence entre --max-time et --connect-timeout ?

L’option --connect-timeout ne couvre que la résolution DNS et les handshakes TCP/TLS/QUIC, et cesse de s’appliquer une fois la connexion établie. L’option --max-time couvre l’ensemble de l’opération du début à la fin, y compris le transfert de la réponse. Utilisez les deux : un délai d’expiration de connexion court pour détecter rapidement les hôtes inactifs, et un délai maximal plus long pour la limite globale.

Pourquoi ma commande curl prend-elle plus de temps que le délai d’expiration que j’ai défini ?

C’est presque toujours dû aux tentatives de réessai. --max-time s’applique à chaque tentative, et --retry ajoute à la fois des tentatives supplémentaires et un délai d’attente exponentiel entre celles-ci. Ajoutez --retry-max-time pour limiter le nombre total de tentatives, et n’oubliez pas que le pire scénario correspond à cette valeur plus une --max-time supplémentaire.

Comment définir un délai d’expiration curl en millisecondes ?

Utilisez une valeur décimale : --connect-timeout 0.25 correspond à 250 millisecondes. Les options --max-time et --connect-timeout acceptent toutes deux les nombres décimaux séparés par un point, une fonctionnalité prise en charge depuis la version 7.32.0 de curl. Il est préférable de ne pas dépasser quelques secondes ; pour des valeurs plus élevées, la précision de la partie décimale se dégrade.

Quel code de sortie curl renvoie en cas de délai d’expiration ?

28, CURLE_OPERATION_TIMEDOUT. Les trois mécanismes de délai d’expiration renvoient ce code ; celui-ci indique donc qu’une limite a été atteinte, mais sans préciser laquelle. À distinguer des codes 7 (connexion refusée) et 6 (échec DNS), qui ont une signification différente et ne doivent généralement pas faire l’objet d’une nouvelle tentative.

Comment limiter la durée d’un téléchargement lent sans interrompre les fichiers volumineux ?

Utilisez --speed-limit et --speed-time à la place de --max-time. Ces options n’interrompent le téléchargement que lorsque le débit reste en dessous d’un seuil pendant une période prolongée ; ainsi, un téléchargement légitime de plusieurs heures n’est pas affecté, tandis qu’un téléchargement bloqué est rapidement interrompu.

Les délais d’expiration fonctionnent-ils différemment via un proxy ?

Oui. --connect-timeout mesure uniquement votre connexion au proxy ; la connexion du proxy vers la cible est prise en compte par --max-time. Les proxys résidentiels ajoutent également une latence réelle, de sorte que les valeurs réglées pour les connexions directes produiront de faux échecs. Effectuez la mesure via le proxy et définissez les valeurs en fonction de celle-ci.

Puis-je définir un délai d’expiration uniquement pour la résolution DNS ?

Pas en tant qu’option distincte — le DNS est inclus dans --connect-timeout. Si vous avez besoin de limiter spécifiquement le DNS, effectuez la résolution séparément et transmettez le résultat avec --resolve, ce qui ignore complètement la recherche effectuée par curl.

En conclusion

Deux options couvrent pratiquement tous les cas de figure : « --connect-timeout » pour un arrêt rapide lorsqu’un hôte est inaccessible, et « --max-time » pour définir la limite maximale globale. Définissez toujours ces deux options, dans chaque script. La valeur par défaut, qui consiste à attendre indéfiniment, est un choix raisonnable pour un outil interactif, mais catastrophique pour l’automatisation.

Il convient de rappeler les deux points qui posent le plus souvent problème. --max-time s’applique à chaque tentative ; ainsi, toute utilisation de --retry doit être accompagnée de --retry-max-time, sans quoi votre commande de dix secondes se transformera en une commande d’une minute. De plus, une limite de temps fixe n’est pas adaptée aux transferts de taille imprévisible : utilisez --speed-limit avec --speed-time pour obtenir un détecteur de blocage qui ne perturbera pas les téléchargements légitimes de longue durée.

Définissez les valeurs à partir de mesures plutôt qu’à partir d’un chiffre rond qui vous semble correct. Une seule exécution de curl -w sur votre cible réelle vous fournit une distribution, et un délai d’expiration dérivé de cette distribution ne se déclenche que lorsqu’il y a véritablement un problème, et non pas simplement lorsque le réseau connaît un après-midi difficile.