Dit artikel bespreekt het concept 'curlese': het gebruik van curl-commando's als onweerlegbaar bewijs bij het debuggen van HTTP-integraties. De auteur analyseert hoe de technische context is veranderd sinds 2021 — met de opkomst van HTTP/3, mTLS en WAF's — en biedt een praktische 'overlevingskit' met essentiële flags en een gids voor veelvoorkomende foutmeldingen om discussies tussen teams te verkorten en problemen sneller op te lossen.
Curlese, vijf jaar later: curl is nog steeds de universele taal van kapotte integraties
Vijf jaar later kan ik bevestigen dat deze these pijnlijk goed stand heeft gehouden. Ik doe dit nog steeds constant. Maar de wereld rondom deze these is behoorlijk veranderd, dus is het tijd voor een update: wat is er veranderd, wat is hetzelfde gebleven en hoe ziet mijn overlevingskit eruit in 2026.
Wat er niet is veranderd
Het sociale probleem bevindt zich precies waar ik het achterliet. Elke integratie omvat nog steeds minstens twee teams, één firewall die niemand volledig begrijpt, en een gesprek dat begint met "bij mij werkt het". Je perfect duidelijke applicatielogs zijn in dat gesprek nog steeds waardeloos, omdat:
- de andere partij jouw logs niet kan (of wil) interpreteren;
- het altijd makkelijker is om aan te nemen dat het probleem bij jou ligt;
- je zelden spreekt met de persoon die het daadwerkelijk kan oplossen.
Een curl-commando met de bijbehorende output lost deze drie problemen op. Het is uitvoerbaar bewijs. Je kunt het in een ticket plakken, de netwerkbeheerder van het andere team kan het zo uitvoeren en het verdict staat in platte tekst geschreven. Dit deel van het artikel behoeft geen enkele update, wat geruststellend of depressing is, afhankelijk van je stemming.
Wat er wel is veranderd
Eigenlijk best veel.
HTTP/2 is overal, HTTP/3 is niet langer exotisch. In 2021 was een eenvoudige HTTP/1.1-uitwisseling de norm voor het soort integraties waar ik mee deal. Nu kom ik regelmatig endpoints tegen die HTTP/2 onderhandelen, en af en toe endpoints waarbij ALPN zelf onderdeel van het probleem is. Wanneer een verzoek vanaf je laptop wel werkt maar vanaf een server vastloopt, is "ze spreken verschillende HTTP-versies" nu een legitieme verdachte.
mTLS ging van exotisch naar alledaags. Clientcertificaten waren vroeger een irritatie die één keer per jaar voorkwam. Nu wil elke tweede B2B-integratie wederzijdse TLS (mutual TLS), wat betekent dat er een geheel nieuwe categorie fouten (en curl-flags) is ontstaan die ik in 2021 niet behandelde.
Alles staat achter een WAF, een proxy of een API-gateway. Dit betekent dat de fout die je krijgt vaak niet van de applicatie komt, maar van een 'uitsmijter' ervoor, met eigen ideeën over welke User-Agent-strings mogen bestaan. Ik heb een keer een middag besteed aan het bewijzen dat een endpoint werkte: de edge van de provider hield simpelweg geen rekening met een specifieke client. De oplossing was letterlijk het wijzigen van een header. Het bewijs was, zoals gewoonlijk, een paar curl-commando's die in één flag verschilden.
De lingua franca heeft een nieuwe spreker gekregen. In 2026 is de entiteit aan wie je het probleem uitlegt steeds vaker geen mens. Een curl-commando met -v output is het perfecte materiaal om in een LLM (Large Language Model) te plakken als je vastloopt: het is complete, ondubbelzinnige context zonder enige setup. Het blijkt dat dezelfde eigenschappen die curl ideaal maken voor tickets, het ook ideaal maken voor prompts. Ook de machines spreken curlese.
De overlevingskit voor 2026
Alles uit het oude bericht is nog steeds van toepassing (-v, -k, --connect-timeout, --trace-ascii, --trace-time — die laatste redde me onlangs nog bij het opsporen van fantoomvertragingen). Hier is wat sindsdien een permanente plek in de kit heeft verdiend:
| Flag | Waarom het in de kit zit |
-w '%{timetotal} %{timeconnect} %{time_appconnect}' | Timing-analyse. Het verschil tussen "je server is traag" en "je TLS-handshake is traag" is het verschil tussen een ticket dat nergens toe leidt en een ticket dat wordt opgelost. |
--resolve host:port:ip | Test een specifiek IP met de juiste SNI/Host, waarbij DNS wordt omzeild. Essentieel wanneer DNS load-balanced is en slechts sommige backends kapot zijn. |
--connect-to ::alt-host | Vergelijkbaar met resolve: leid de verbinding elders heen terwijl de headers intact blijven. Geweldig voor het testen van een staging-backend met productie-URL's. |
--cert client.pem --key client.key | mTLS. De helft van de tijd is de fout de certificaatketen, en curl vertelt je precies welk certificaat hij heeft verzonden en wat de server daarover zei. |
--json | Stelt Content-Type: application/json in en voert een POST uit. Een klein detail, maar het verwijdert een hele klasse aan "je bent een header vergeten"-fouten bij het schrijven van repro-commando's. |
--fail-with-body | De exitcode weerspiegelt de HTTP-status, maar je ziet nog steeds de response body van de fout. Perfect voor scripts en voor mensen. |
--retry 5 --retry-all-errors | "Het faalt soms" is geen acceptabel bugrapport meer. Laat statistieken het woord doen. |
--no-alpn | Voor die speciale middagen waarop je vermoedt dat de HTTP-versieonderhandeling zelf het probleem is. Zeldzaam, maar als je het nodig hebt, is er niets anders dat werkt. |
Een opmerking over -w: de formatstring is volledig aanpasbaar en wordt crimineel onderbenut. curl -o /dev/null -s -w 'dns:%{timenamelookup} connect:%{timeconnect} tls:%{timeappconnect} total:%{timetotal} http:%{http_code}\n' https://example.com geeft je een analyse in één regel van elk endpoint. Ik heb dit als een shell-alias (ik noem het 'curlopsy'). Dat zou jij ook moeten doen.
Het woordenboek, bijgewerkt
Het oude bericht had een lijst met veelvoorkomende foutmeldingen en hun gebruikelijke oorzaken. Hier is de editie van 2026:
| Symptoom | Betekent waarschijnlijk |
connection timed out | Geen netwerkpad. Firewall, routing, of de service is down. Nog steeds de nummer 1 hit. |
connection refused | Pad bestaat, maar er luistert niets op die poort. Service down of verkeerde poort. |
SSL certificate problem: unable to get local issuer certificate | Zelfondertekend certificaat of een CA die je trust store niet kent. Klassiek en eeuwig. |
sslv3 alert handshake failure / curl: (35) | TLS-versies of cipher suites overlappen niet. Vaak een antieke server die een moderne client tegenkomt, of vice versa. |
wrong version number | Je spreekt TLS tegen een gewone HTTP-poort. Of er is een proxy die dingen in het midden vervormt. |
HTTP/2 stream errors / resets (die verdwijnen met --http1.1) | Een middlebox of server met een bugge HTTP/2 implementatie. Downgrade en test opnieuw voordat je iemand beschuldigt. |
403 met een HTML-pagina van een product dat je nooit hebt gehoord | Dat is de WAF (Web Application Firewall). Lees de pagina: meestal staat er wel welke vendor het is, wat je vertelt wiens edge je blokkeert. |
Het werkt met --insecure maar niet zonder | Probleem met de certificaatketen. Nu weet je precies waar je moet graven. |
De boodschap verspreiden, herladen
Het oude bericht sloot af met een lijst zinnen om een curl-sessie aan te vragen bij je gesprekspartner. Hier is het Engelse starterpakket voor 2026:
- "Can you curl it from your side and paste the output in the ticket?"
- "Let’s both run the same command and compare notes."
- "Send me the -v output, not a screenshot of Postman."
- "You either curl it yourself, or I will curl the hell out of you."
Vijf jaar later is mijn advies ongewijzigd: wanneer een integratie kapot gaat, ga niet discussiëren, maar curl het! Het commando is het contract, de output is het verdict en het ticket lost zichzelf op. Sommige technologieën komen en gaan; de bescheiden curl-aanroep is blijkbaar voor altijd.
***
Voetnoten:
- Het originele bericht is hier beschikbaar als je Italiaans leest. 'Curlese' vertaalt niet echt; het is 'curl' omgezet in een taalnaam, met werkwoorden zoals curlare en zelfstandige naamwoorden zoals curlata (een enkele curl-aanroep, meestal uitgevoerd in woede).
- Het wordt 'curlopsy' genoemd (curl + autopsy). Ja, het is een verschrikkelijke naam. Nee, ik verander hem niet: hij heeft twee laptops overleefd en heeft op dit punt senioriteit.
- Niets tegen Postman. Maar een screenshot van een GUI is geen reproduceerbare testcase, en dat weet je.
- De levering is belangrijk: doodserieus, op papier, en alleen bij iemand met wie je al minstens één incident-bridge hebt overleefd. HR-afdelingen zijn berucht om hun gebrek aan vloeiend curlese.
- Ja, werkwoord. Het Italiaanse origineel sloot af met "diffondete il verbo!" — en in het Italiaans betekent verbo zowel "het woord" als "het werkwoord", wat het de enige correcte vertaling maakt. Curl is nu een werkwoord, vervoeg het met trots.
Curlese, vijf jaar later: curl is nog steeds de universele taal van kapotte integraties
Vijf jaar later kan ik bevestigen dat deze these pijnlijk goed stand heeft gehouden. Ik doe dit nog steeds constant. Maar de wereld rondom deze these is behoorlijk veranderd, dus is het tijd voor een update: wat is er veranderd, wat is hetzelfde gebleven en hoe ziet mijn overlevingskit eruit in 2026.
Wat er niet is veranderd
Het sociale probleem bevindt zich precies waar ik het achterliet. Elke integratie omvat nog steeds minstens twee teams, één firewall die niemand volledig begrijpt, en een gesprek dat begint met "bij mij werkt het". Je perfect duidelijke applicatielogs zijn in dat gesprek nog steeds waardeloos, omdat:
- de andere partij jouw logs niet kan (of wil) interpreteren;
- het altijd makkelijker is om aan te nemen dat het probleem bij jou ligt;
- je zelden spreekt met de persoon die het daadwerkelijk kan oplossen.
Een curl-commando met de bijbehorende output lost deze drie problemen op. Het is uitvoerbaar bewijs. Je kunt het in een ticket plakken, de netwerkbeheerder van het andere team kan het zo uitvoeren en het verdict staat in platte tekst geschreven. Dit deel van het artikel behoeft geen enkele update, wat geruststellend of depressing is, afhankelijk van je stemming.
Wat er wel is veranderd
Eigenlijk best veel.
HTTP/2 is overal, HTTP/3 is niet langer exotisch. In 2021 was een eenvoudige HTTP/1.1-uitwisseling de norm voor het soort integraties waar ik mee deal. Nu kom ik regelmatig endpoints tegen die HTTP/2 onderhandelen, en af en toe endpoints waarbij ALPN zelf onderdeel van het probleem is. Wanneer een verzoek vanaf je laptop wel werkt maar vanaf een server vastloopt, is "ze spreken verschillende HTTP-versies" nu een legitieme verdachte.
mTLS ging van exotisch naar alledaags. Clientcertificaten waren vroeger een irritatie die één keer per jaar voorkwam. Nu wil elke tweede B2B-integratie wederzijdse TLS (mutual TLS), wat betekent dat er een geheel nieuwe categorie fouten (en curl-flags) is ontstaan die ik in 2021 niet behandelde.
Alles staat achter een WAF, een proxy of een API-gateway. Dit betekent dat de fout die je krijgt vaak niet van de applicatie komt, maar van een 'uitsmijter' ervoor, met eigen ideeën over welke User-Agent-strings mogen bestaan. Ik heb een keer een middag besteed aan het bewijzen dat een endpoint werkte: de edge van de provider hield simpelweg geen rekening met een specifieke client. De oplossing was letterlijk het wijzigen van een header. Het bewijs was, zoals gewoonlijk, een paar curl-commando's die in één flag verschilden.
De lingua franca heeft een nieuwe spreker gekregen. In 2026 is de entiteit aan wie je het probleem uitlegt steeds vaker geen mens. Een curl-commando met -v output is het perfecte materiaal om in een LLM (Large Language Model) te plakken als je vastloopt: het is complete, ondubbelzinnige context zonder enige setup. Het blijkt dat dezelfde eigenschappen die curl ideaal maken voor tickets, het ook ideaal maken voor prompts. Ook de machines spreken curlese.
De overlevingskit voor 2026
Alles uit het oude bericht is nog steeds van toepassing (-v, -k, --connect-timeout, --trace-ascii, --trace-time — die laatste redde me onlangs nog bij het opsporen van fantoomvertragingen). Hier is wat sindsdien een permanente plek in de kit heeft verdiend:
| Flag | Waarom het in de kit zit |
-w '%{timetotal} %{timeconnect} %{time_appconnect}' | Timing-analyse. Het verschil tussen "je server is traag" en "je TLS-handshake is traag" is het verschil tussen een ticket dat nergens toe leidt en een ticket dat wordt opgelost. |
--resolve host:port:ip | Test een specifiek IP met de juiste SNI/Host, waarbij DNS wordt omzeild. Essentieel wanneer DNS load-balanced is en slechts sommige backends kapot zijn. |
--connect-to ::alt-host | Vergelijkbaar met resolve: leid de verbinding elders heen terwijl de headers intact blijven. Geweldig voor het testen van een staging-backend met productie-URL's. |
--cert client.pem --key client.key | mTLS. De helft van de tijd is de fout de certificaatketen, en curl vertelt je precies welk certificaat hij heeft verzonden en wat de server daarover zei. |
--json | Stelt Content-Type: application/json in en voert een POST uit. Een klein detail, maar het verwijdert een hele klasse aan "je bent een header vergeten"-fouten bij het schrijven van repro-commando's. |
--fail-with-body | De exitcode weerspiegelt de HTTP-status, maar je ziet nog steeds de response body van de fout. Perfect voor scripts en voor mensen. |
--retry 5 --retry-all-errors | "Het faalt soms" is geen acceptabel bugrapport meer. Laat statistieken het woord doen. |
--no-alpn | Voor die speciale middagen waarop je vermoedt dat de HTTP-versieonderhandeling zelf het probleem is. Zeldzaam, maar als je het nodig hebt, is er niets anders dat werkt. |
Een opmerking over -w: de formatstring is volledig aanpasbaar en wordt crimineel onderbenut. curl -o /dev/null -s -w 'dns:%{timenamelookup} connect:%{timeconnect} tls:%{timeappconnect} total:%{timetotal} http:%{http_code}\n' https://example.com geeft je een analyse in één regel van elk endpoint. Ik heb dit als een shell-alias (ik noem het 'curlopsy'). Dat zou jij ook moeten doen.
Het woordenboek, bijgewerkt
Het oude bericht had een lijst met veelvoorkomende foutmeldingen en hun gebruikelijke oorzaken. Hier is de editie van 2026:
| Symptoom | Betekent waarschijnlijk |
connection timed out | Geen netwerkpad. Firewall, routing, of de service is down. Nog steeds de nummer 1 hit. |
connection refused | Pad bestaat, maar er luistert niets op die poort. Service down of verkeerde poort. |
SSL certificate problem: unable to get local issuer certificate | Zelfondertekend certificaat of een CA die je trust store niet kent. Klassiek en eeuwig. |
sslv3 alert handshake failure / curl: (35) | TLS-versies of cipher suites overlappen niet. Vaak een antieke server die een moderne client tegenkomt, of vice versa. |
wrong version number | Je spreekt TLS tegen een gewone HTTP-poort. Of er is een proxy die dingen in het midden vervormt. |
HTTP/2 stream errors / resets (die verdwijnen met --http1.1) | Een middlebox of server met een bugge HTTP/2 implementatie. Downgrade en test opnieuw voordat je iemand beschuldigt. |
403 met een HTML-pagina van een product dat je nooit hebt gehoord | Dat is de WAF (Web Application Firewall). Lees de pagina: meestal staat er wel welke vendor het is, wat je vertelt wiens edge je blokkeert. |
Het werkt met --insecure maar niet zonder | Probleem met de certificaatketen. Nu weet je precies waar je moet graven. |
De boodschap verspreiden, herladen
Het oude bericht sloot af met een lijst zinnen om een curl-sessie aan te vragen bij je gesprekspartner. Hier is het Engelse starterpakket voor 2026:
- "Can you curl it from your side and paste the output in the ticket?"
- "Let’s both run the same command and compare notes."
- "Send me the -v output, not a screenshot of Postman."
- "You either curl it yourself, or I will curl the hell out of you."
Vijf jaar later is mijn advies ongewijzigd: wanneer een integratie kapot gaat, ga niet discussiëren, maar curl het! Het commando is het contract, de output is het verdict en het ticket lost zichzelf op. Sommige technologieën komen en gaan; de bescheiden curl-aanroep is blijkbaar voor altijd.
***
Voetnoten:
- Het originele bericht is hier beschikbaar als je Italiaans leest. 'Curlese' vertaalt niet echt; het is 'curl' omgezet in een taalnaam, met werkwoorden zoals curlare en zelfstandige naamwoorden zoals curlata (een enkele curl-aanroep, meestal uitgevoerd in woede).
- Het wordt 'curlopsy' genoemd (curl + autopsy). Ja, het is een verschrikkelijke naam. Nee, ik verander hem niet: hij heeft twee laptops overleefd en heeft op dit punt senioriteit.
- Niets tegen Postman. Maar een screenshot van een GUI is geen reproduceerbare testcase, en dat weet je.
- De levering is belangrijk: doodserieus, op papier, en alleen bij iemand met wie je al minstens één incident-bridge hebt overleefd. HR-afdelingen zijn berucht om hun gebrek aan vloeiend curlese.
- Ja, werkwoord. Het Italiaanse origineel sloot af met "diffondete il verbo!" — en in het Italiaans betekent verbo zowel "het woord" als "het werkwoord", wat het de enige correcte vertaling maakt. Curl is nu een werkwoord, vervoeg het met trots.