11 min leestijdEngineering

Redirect-lus: hoe je ERR_TOO_MANY_REDIRECTS vindt en oplost

Een redirect-lus stuitert de browser heen en weer tussen URL's totdat hij het opgeeft. Traceer de redirectketen met één commando, benoem de regel die niet overeenstemt, en los het definitief op.

Marius Voß
DevRel · edge infra
Een redirect-lus getekend als twee URL's die naar elkaar terugwijzen terwijl de hopteller van de browser opraakt en ERR_TOO_MANY_REDIRECTS teruggeeft

Een redirect-lus is een keten van HTTP-redirects die nooit landt: URL A stuurt de browser naar URL B, B stuurt hem terug naar A, en na ongeveer twintig hops stopt de browser met proberen en toont ERR_TOO_MANY_REDIRECTS. Er is niets kapot op de bestemmingspagina. Twee regels zijn het simpelweg oneens over waar de URL thuishoort, en de ene maakt telkens ongedaan wat de andere doet.

Een lussende redirect is een van de weinige webfouten die zijn eigen oorzaak benoemt, zolang je naar het juiste kijkt. Niet de browser, niet de foutpagina, en zeker niet de cache: de redirectketen. Elke hop draagt een Location header, en de twee adressen die zich blijven herhalen zijn de twee regels die je moet verzoenen. Deze gids doorloopt de diagnose in één commando, de oorzaken achter bijna elke redirectcyclus die ik ooit heb moeten ontrafelen, en de oplossing die niet stiekem ergens anders een tweede lus creëert. Als de redirectfamilie zelf vaag is, is soorten URL-redirects de kaart; dit is de troubleshootingversie.

Wat ERR_TOO_MANY_REDIRECTS eigenlijk betekent

Browsers volgen redirects namens jou, maar niet eeuwig. Elke client houdt een hopbudget bij en laat het verzoek vallen zodra dat op is: Chrome stopt bij 20 en laat je dat niet wijzigen, Firefox levert dezelfde standaardwaarde onder network.http.redirection-limit, en curl staat er 50 toe voordat hij klaagt. De standaard laat het getal open. RFC 9110 zegt alleen dat een client cyclische redirects moet detecteren en erop moet ingrijpen, wat de beleefde manier van de spec is om te zeggen dat elke browser een stroomonderbreker nodig heeft.

Dat onderscheid is belangrijk voor de diagnose, want de foutmelding bewijst helemaal niet dat er een cyclus is. Een keten van eenentwintig verschillende hops zonder herhalingen triggert precies dezelfde melding als twee URL's die eindeloos heen en weer kaatsen. Beide zijn de moeite van het oplossen waard, maar slechts een van de twee heeft een paar adressen om te verzoenen. MDN's redirect-referentie behandelt beide vormen, en het praktische verschil verschijnt zodra je de keten afdrukt.

Een redirect-lus tussen een HTTPS-URL en een HTTP-URL, waarbij de hopteller van de browser zijn limiet bereikt en ERR_TOO_MANY_REDIRECTS teruggeeft

Nog iets dat de foutpagina verbergt: een permanente redirect wordt door de browser gecachet. Als de lus is opgebouwd uit 301-responses, blijven bezoekers lokaal lussen, zelfs nadat je de server hebt gerepareerd, totdat die cache-entry verloopt of ze hem wissen. Precies dat is waarom ik redirectwijzigingen test met een 302 en pas naar 301 promoveer zodra de keten klopt, een gewoonte waar 301 vs. 302 redirects het volledige pleidooi voor houdt.

Traceer de redirectketen met één commando

Sla de browser over. De snelste manier om een redirect-lus te doorgronden is de terminal, omdat curl elke hop afdrukt in plaats van ze samen te persen tot één foutpagina:

curl -sIL https://example.com | grep -E '^HTTP|^[Ll]ocation'

Je krijgt een statusregel en een Location header per hop, in volgorde. Lees van boven naar beneden en een van drie patronen duikt op. Twee URL's die elkaar afwisselen betekent een echte cyclus, en het paar noemt beide overtredende regels. Een lange mars van verschillende URL's betekent een keten die iemand in de loop der jaren heeft opgestapeld, waarbij elke hop op zichzelf legitiem is. En een keten die in de terminal prima oplost maar in een browser toch faalt, betekent dat de lus door cookies wordt aangedreven, aangezien curl standaard geen cookies verstuurt.

Dat laatste geval verdient een eigen controle, want het is degene waardoor mensen een middag lang hun DNS de schuld geven:

curl -sIL -c jar.txt -b jar.txt https://example.com/account | grep -E '^HTTP|^[Ll]ocation'

Met een cookiejar erbij reproduceert een login- of consentlus zich op de commandoregel, waar je daadwerkelijk kunt zien welk endpoint de sessie steeds instelt en vervolgens afwijst. In de browser is het equivalent het Network-paneel met "Preserve log" ingeschakeld, wat voorkomt dat eerdere hops worden gewist zodra de pagina navigeert. Wil je liever helemaal geen terminal openen, dan traceert onze linkchecker de keten in de browser en drukt hij bij elke hop de statuscode af.

De oorzaken achter bijna elke redirectcyclus

Zodra je de keten kunt zien, is de oorzaak meestal een van een klein handjevol. Het herhalende paar URL's vertelt je naar welke laag je moet kijken: het scheme dat heen en weer klapt wijst op TLS-terminatie, de hostnaam die omslaat wijst op een canonical-host-regel, en een pad dat steeds een slash wint en verliest wijst op de volgorde van rewrites.

https-regels achter een proxy die TLS termineert

Dit is de meest voorkomende oneindige redirect op het moderne web, en hij verscheen op het moment dat proxy's TLS begonnen te termineren voor origins. De proxy accepteert een HTTPS-verzoek van de bezoeker en haalt vervolgens je origin op via gewoon HTTP. Je origin ziet een onveilig verzoek, doet wat je hem hebt opgedragen, en stuurt door naar HTTPS. De proxy serveert die redirect, wordt opnieuw aangevraagd, haalt de origin weer op via HTTP, en zo gaat het rond. Cloudflare documenteert precies dit falen onder zijn flexible-encryptiemodus, en elke andere proxy heeft dezelfde valkuil onder een andere naam.

Er zijn twee schone oplossingen. Zet de proxy op een volledige encryptiemodus zodat hij via TLS met je origin praat, wat in bijna elk geval het juiste antwoord is. Of, als de hop naar de origin echt onversleuteld moet blijven, laat de regel van de origin de X-Forwarded-Proto header lezen in plaats van de ruwe verbinding, zodat hij stopt met het doorsturen van verzoeken die aan de edge al veilig waren.

www en apex het oneens over welke host wint

Eén canonical-host-regel is prima. Twee ervan, op verschillende momenten door verschillende mensen geschreven, vormen een lus. De klassieke versie heeft een serverconfig die de apex naar www stuurt terwijl de applicatieconfig www terugstuurt naar de apex, en beide zijn ervan overtuigd dat ze gelijk hebben. Je ziet het meteen in de keten: example.com naar www.example.com naar example.com, eindeloos.

Kies één host, dwing die af op precies één plek, en verwijder de andere regel in plaats van te proberen ze het met elkaar eens te maken. Hetzelfde geldt voor een trailing-slash- of lowercase-rewrite: wanneer twee regels dezelfde URL in tegengestelde richtingen normaliseren, krijg je een redirectcyclus, ook al is elke regel op zichzelf zinnig.

de CMS- of app-URL-instelling die niet meer klopt

De meeste applicaties slaan hun eigen canonieke adres op, en dat veld is een redirectregel met een vriendelijke naam. Verander het domein, verhuis naar een nieuwe omgeving, of herstel een databasesnapshot van een andere host, en de app begint elk verzoek door te sturen naar een adres dat terugstuurt. Omdat de instelling in de database staat in plaats van in je webserverconfig, overleeft hij de configaudit die je net hebt gedaan, wat hem zo vervelend maakt om te vinden.

Het kenmerk is een keten die je huidige hostnaam verlaat en er nooit naar terugkeert. Corrigeer het opgeslagen adres naar het domein dat je daadwerkelijk serveert, en leeg dan elke applicatie- of paginacache die het verkeerde adres heeft vastgelegd.

Hier zijn de regels onschuldig en is de status het probleem. Een poort stuurt niet-geauthenticeerde bezoekers door naar een loginpagina, de loginpagina stuurt geauthenticeerde bezoekers terug, en een sessiecookie die niet op het doeldomein kan worden gelezen laat beide kanten ervan overtuigd zijn dat de andere het moet afhandelen. Consentbanners veroorzaken dezelfde vorm wanneer de redirect die de consentcookie instelt zelf wordt geblokkeerd.

Het teken is hetzelfde als in de vorige sectie: een schoon incognitovenster werkt, of curl zonder cookiejar lost normaal op. Controleer het domein en de Path-scope van de cookie, de Secure- en SameSite-attributen tegen het scheme dat je daadwerkelijk serveert, en of hij op de apex wordt ingesteld terwijl hij op www wordt gelezen.

Wat zich herhaalt in de ketenWaarschijnlijke oorzaakEerste ding om te wijzigen
http naar https en terugProxy termineert TLS, origin blijft aandringenVolledige encryptiemodus, of vertrouw XFP
Apex naar www en terugTwee canonical-host-regelsVerwijder er een, houd één regel over
Een pad dat een slash wint en verliestRewrite-regels in de verkeerde volgordeEenmalig normaliseren, vóór alle routing
Verlaat je hostnaam, keert nooit terugOpgeslagen site-adres is verouderdCorrigeer de URL-instelling van de app, purge

Redirect-lussen zijn zelden mysterieus zodra de keten op het scherm staat, maar ze kosten wel een middag als je gist in plaats van traceert. Wil je liever eigenaar zijn van de redirectlaag dan ermee in discussie gaan, dan geeft het gratis plan van Elido je links waarvan de bestemming een enkele opgeslagen waarde is die je kunt omleggen, met elke hop gelogd.

Los het op zonder een tweede lus te creëren

De reparatie zelf is kort, en de volgorde is belangrijker dan de syntax. Verander één regel, traceer dan opnieuw. Drie veranderen en herladen vertelt je niets over welke ertoe deed, en ik heb een team op die manier een uur zien besteden aan een lus die werd veroorzaakt door een regel die ze bij de eerste poging al hadden gerepareerd.

  1. Verwijder of keer exact een van de twee regels om die de keten aanwees, zodat een verzoek in één hop een 200 kan bereiken.
  2. Voer de curl -sIL-trace opnieuw uit en bevestig dat de keten nu hooguit één redirect telt, zonder herhaalde hostnaam.
  3. Wis de cache van de browser, of test in een incognitovenster, want elke 301 die je eerder hebt geserveerd is nog steeds lokaal gecachet en zal een falen voorwenden dat niet meer bestaat.
  4. Promoveer tijdelijke redirects pas naar permanente zodra de vorm van de keten vaststaat.

Aan het eind van die lijst liggen twee valkuilen. HSTS is er een: zodra een host een Strict-Transport-Security header heeft verstuurd, upgraden browsers zelf elk verzoek naar HTTPS, waardoor een origin-regel die ook HTTPS afdwingt overbodig wordt en een proxy-misconfiguratie kan omslaan in een lus die je niet kunt reproduceren zonder de HSTS-entry te wissen. De andere is caching voor de lus. Een CDN die een 301 heeft gecachet, blijft die vrolijk serveren nadat de origin ermee is gestopt, en dat is waarom een purge bij de oplossing hoort in plaats van erna. Lange ketens die nooit lussen, zijn het waard om in dezelfde beurt in te korten: elke extra hop is weer een kans dat een querystring wegvalt, wat precies is hoe UTM-parameters verdwijnen in GA4, en het is deel van de reden waarom korte links SEO niet hoeven te schaden zolang ze één hop diep blijven.

Voor- en na-weergave van een redirectketen: een keten van vier hops die tussen hosts lust, en hetzelfde verzoek opgelost door een enkele canonieke redirect

Korte links voegen nog een plek toe waar een cyclus kan ontstaan, en dat is niet de redirect van de shortener. Een korte link is een enkele opgeslagen hop: slug erin, bestemming eruit. De lus verschijnt wanneer de bestemming terugwijst, wat vaker voorkomt dan het klinkt. Iemand bewerkt een campagnelink zodat die naar een landingspagina wijst, de landingspagina heeft een oude regel die doorstuurt naar de korte URL omdat dat vorig kwartaal het canonieke deeladres was, en nu kaatsen de twee heen en weer. Beide hops gedragen zich precies zoals geconfigureerd.

Nog twee varianten verschijnen in dezelfde keten. De ene is een paar korte links die na een bulkbewerking naar elkaar wijzen, meestal afkomstig van een spreadsheetimport waarbij de bestemmingskolom korte URL's bevatte in plaats van uiteindelijke. De andere is een aangepast domein dat nog steeds resolvet naar een host die terugstuurt naar de shortener, wat een DNS-restant is en geen linkprobleem, en aangepaste domeinen voor korte links behandelt hoe de records eruit moeten zien. In alle drie de gevallen is de oplossing om de bestemming op de uiteindelijke pagina te zetten in plaats van op nog een redirect, wat je kunt doen zonder iets aan te raken dat al is afgedrukt of gepubliceerd.

Omdat de bestemming is opgeslagen in plaats van in de URL gebakken, hoeft niets hiervan herdrukt te worden. Dat is het hele argument voor beheerde links, en korte link werkt niet is de bredere triagegids voor wanneer het symptoom niet specifiek een lus is.

Voorkom dat de volgende de deur uit gaat

Redirect-lussen zijn een configuratie-drift-bug, dus de duurzame oplossingen zijn de saaie. Houd de canonical-host-beslissing op één plek en behandel elke tweede regel die scheme of hostnaam raakt als een bug zodra je hem ziet. Traceer nieuwe redirects met curl -sIL voordat je ze aankondigt, niet nadat iemand een blanco pagina meldt. Als links ertoe doen voor omzet, zet er een controle op: een geplande trace die faalt zodra de keten langer wordt dan één hop, vangt drift lang voordat een klant dat doet, en linkredirects monitoren met Sentry en Datadog laat zien hoe dat eruitziet als het is aangesloten op echte alerting.

De bredere gewoonte is bestemmingen behandelen als data die je kunt auditen. Linkrotpreventie behandelt dezelfde discipline voor links die stilletjes stoppen met resolven, en het is hoe dan ook dezelfde wekelijkse controle. Eerlijk gezegd zijn de meeste lussen die ik heb gezien de deur uit gegaan doordat twee competente mensen, een maand na elkaar, elk hetzelfde probleem in een andere laag oplosten. Schrijf de regel één keer op en de lus wordt onmogelijk.

Lees de cornerstone-serie

Dit artikel valt onder de engineering-cluster. Voor de vorm van het redirectpad zelf behandelt p95 onder 15ms halen voor redirects wat een enkele goed gedragen hop kost, en soorten URL-redirects behandelt welke statuscode waar hoort voordat je regels begint te stapelen.

Gerelateerd op de blog

Veelgestelde vragen

Wat betekent ERR_TOO_MANY_REDIRECTS?

Het betekent dat de browser de ene redirect na de andere volgde zonder ooit een echte pagina te bereiken, zijn hoplimiet bereikte, en stopte. De pagina zelf is meestal in orde; twee redirectregels zijn het oneens over waar de URL thuishoort, waardoor de ene steeds ongedaan maakt wat de andere doet. Chrome toont ERR_TOO_MANY_REDIRECTS, Firefox meldt dat de pagina niet goed doorstuurt, en Safari meldt dat er te veel redirects hebben plaatsgevonden.

Hoe los ik ERR_TOO_MANY_REDIRECTS op?

Traceer eerst de keten, en verwijder dan een van de twee regels die om de URL vechten. Voer curl -sIL uit op het adres en lees elke Location header: het paar URL's dat zich blijft herhalen vertelt je welke regel je moet verwijderen of omkeren. De gebruikelijke boosdoeners zijn een HTTPS-regel die achter een proxy draait die TLS termineert, een www-regel bovenop nog een www-regel, en een site-adresinstelling die niet meer overeenkomt met het domein dat wordt geserveerd.

Hoeveel redirects volgt een browser voordat hij het opgeeft?

Ongeveer twintig, afhankelijk van de browser. Chrome stopt na 20 hops en die limiet is niet instelbaar, Firefox stelt hetzelfde plafond beschikbaar als network.http.redirection-limit met een standaardwaarde van 20, en curl volgt er tot 50 tenzij je --max-redirs wijzigt. De spec legt geen getal vast: RFC 9110 zegt alleen dat een client cyclische redirects moet detecteren en erop moet ingrijpen, dus elke client kiest zijn eigen plafond.

Lost het wissen van cookies een redirectlus op?

Soms, en dat vertelt je iets. Als een incognitovenster de pagina wel gewoon laadt, wordt de lus veroorzaakt door een verouderde sessie- of consentcookie, niet door je serverregels, en is wissen een echte oplossing voor die bezoeker. Als de lus ook in een vers incognitovenster optreedt, zijn cookies onschuldig en zit het probleem in een redirectregel, een proxy-instelling, of een CMS-URL-veld.

Waarom begon mijn site te lussen nadat ik HTTPS of een CDN-proxy inschakelde?

Omdat twee lagen nu allebei op HTTPS staan terwijl een van beide met je origin over gewoon HTTP praat. De proxy vraagt de origin op poort 80 aan, de regel van de origin stuurt hem terug naar HTTPS, de proxy beantwoordt dat verzoek op dezelfde manier, en de cyclus stopt nooit. Zet de encryptiemodus van de proxy op volledig zodat hij de origin via TLS ophaalt, of laat je regel de X-Forwarded-Proto header vertrouwen in plaats van de ruwe verbinding.

Kan een korte link een redirectlus veroorzaken?

Ja, wanneer de bestemming terugwijst naar de korte link, of wanneer twee links naar elkaar wijzen. De meest voorkomende versie is een link bewerken naar een pagina die zelf weer doorstuurt naar de korte URL, en die overleeft elke browserverversing omdat beide hops precies doen wat is geconfigureerd. Stel de bestemming in op de uiteindelijke pagina in plaats van op nog een redirect, en de lus verdwijnt zonder dat er iets herdrukt hoeft te worden.

Probeer Elido

Plak een URL, krijg een werkende korte link

Geen aanmelding nodig. Link blijft 30 dagen actief. Meld je aan om hem voor altijd te bewaren.

Gratis, geen aanmelding nodig · 2 per dag

Probeer Elido

In de EU gehoste URL-shortener met aangepaste domeinen, uitgebreide analyses en een open API. Gratis abonnement - geen creditcard nodig.

Tags
redirect loop
err_too_many_redirects
too many redirects
redirect chain
infinite redirect
301 redirect loop

Verder lezen