Je publiceert een nieuwe post, of je bezoekt een URL waarvan je zeker weet dat hij live staat, en in plaats van de pagina krijg je "404 Not Found". De URL klopt. De post staat op gepubliceerd. Andere pagina's op dezelfde site laden prima. Soms geeft één URL 404, soms een hele categorie en soms doen ineens alle mooie permalinks het niet meer terwijl jouwsite.nl/?p=123 nog gewoon werkt.
Wat een 404 in deze context eigenlijk betekent
RFC 9110 §15.5.5 definieert een 404 als: "the origin server did not find a current representation for the target resource or is not willing to disclose that one exists." In gewone taal: de webserver heeft naar de URL gekeken, aan WordPress gevraagd wat die ermee moest doen, en WordPress had niks om terug te geven.
Op een WordPress-site betekent dat bijna altijd dat de vertaling van URL naar post stuk is. WordPress gebruikt rewrite rules om een mooie URL als /blog/hello-world/ om te zetten in een query naar de post met slug hello-world. Die regels staan opgeslagen in de database en, op Apache, óók uitgeschreven in .htaccess. Zodra die keten ergens breekt, kan WordPress de URL niet meer koppelen aan een post en valt het verzoek door naar de 404-template. De post bestaat nog gewoon. Het pad ernaartoe is weg.
Eén snelle test scheidt dit type 404 van alle andere oorzaken. Bezoek jouwsite.nl/?p=123 (vervang 123 door het echte post-ID dat je in het admin-scherm in de URL ziet, zoals post.php?post=123). Laadt die URL de post? Dan is de content in orde en zit het probleem in de rewrite-laag. Geeft de ?p=123 versie óók 404, dan is de post echt weg of niet gepubliceerd, en dat is een hele andere fix. En zie je op elke URL een hele andere foutmelding (een witte pagina, een algemene crash), dan kijk je waarschijnlijk naar de "Er is een kritieke fout opgetreden"-melding of een 403 Forbidden, niet naar een 404.
Veelvoorkomende oorzaken, op volgorde van waarschijnlijkheid
1. De rewrite rules zijn verouderd en moeten opnieuw gegenereerd worden
Dit is verreweg de meest voorkomende oorzaak. WordPress cachet zijn rewrite rules in de database-optie rewrite_rules. Die cache wordt alleen opnieuw opgebouwd als WordPress de functie flush_rewrite_rules() aanroept, wat onder andere gebeurt bij plugin-activatie, theme-wissel en het opslaan van permalink-instellingen. Tussen die momenten blijft de cache staan zoals hij was. Als een plugin een nieuwe rewrite rule heeft geregistreerd maar vergat te flushen, of als een migratie oude rules van de vorige site heeft laten staan, dan resolved de mooie URL niet meer. Symptoom: in het dashboard staat de post keurig op de juiste slug, de ?p= versie werkt, maar de mooie URL geeft 404.
2. De post of pagina is verplaatst, offline gehaald of de slug is veranderd
De op één na meest voorkomende oorzaak, en de oorzaak waar mensen zich meestal wat ongemakkelijk bij voelen als ze hem vinden. De permalink die de bezoeker aanroept, bestaat gewoon niet meer op de site. De slug is aangepast in een revisie. De post is teruggezet naar concept. De pagina staat in de prullenbak. Een URL die ooit live was heeft nu geen bijbehorende post meer, dus WordPress geeft een echte 404 terug. Dat is technisch gezien het juiste antwoord. De ?p=123 test vangt dit: als ook die URL 404 geeft, is de post wat WordPress betreft weg.
3. De .htaccess rewrite-regels ontbreken of zijn stuk (alleen Apache)
Zit je op Apache of LiteSpeed, dan lopen alle mooie URL's op je site via het WordPress-blok in .htaccess. Als dat blok weg is, of het bestand staat er helemaal niet meer, dan geven alle niet-homepage URL's 404 terwijl de homepage gewoon blijft werken. Ik zie dit het vaakst na een migratie waarbij bestanden zijn gekopieerd maar verborgen bestanden werden overgeslagen, nadat een security-tool .htaccess heeft overschreven met een strengere variant die niet meer naar index.php routeert, of nadat een chmod het bestand onleesbaar heeft gemaakt. nginx leest .htaccess niet, dus op nginx kun je deze oorzaak overslaan.
Een kapotte .htaccess is ook de meest voorkomende oorzaak achter de ERR_TOO_MANY_REDIRECTS-melding en draagt regelmatig bij aan de 500 Internal Server Error. Zie je 404's tegelijk met een van die twee op dezelfde site? Fix .htaccess eerst, dan lossen de andere twee zich vaak vanzelf op.
4. De rewrite op serverniveau klopt niet (nginx of Apache)
Op nginx heeft WordPress try_files $uri $uri/ /index.php?$args; nodig in het location / blok. Zonder die directive ziet nginx dat /blog/hello-world/ geen bestand op schijf is en geeft hij 404 terug voordat PHP er ook maar aan te pas komt. Op Apache is het parallelle probleem dat mod_rewrite op moduleniveau uitstaat, of dat AllowOverride op None staat waardoor Apache .htaccess gewoon negeert. Symptoom op allebei: alle mooie URL's geven 404, de ?p=123 versie werkt, en zelfs permalinks opnieuw opslaan helpt niet omdat de rewrite-laag bóven WordPress het probleem is.
5. De multisite-subdirectory rewrite-regels ontbreken
WordPress Multisite in subdirectory-modus heeft extra rewrite-regels nodig die een single-site installatie niet heeft, en die regels werken alleen als ze netjes in .htaccess (Apache) of in het nginx server block staan. Na een migratie, na een WordPress core-update die de default rules aanpaste, of na een handmatige edit die per ongeluk de multisite-specifieke regels eruit knipte, geven alle subsites behalve de hoofdsite ineens 404 op elke pagina. Heb je een subdirectory multisite en geven alle subsites 404? Dan is dit vrijwel altijd de oorzaak.
Uitzoeken welke oorzaak het is
Loop deze checks op volgorde door. Ze zijn niet-destructief en vertellen je precies welke van de vijf oorzaken het is vóórdat je ook maar iets aanpast.
Check 1: werkt de ?p=123 versie? Zoek het post-ID in het dashboard op (je ziet het in de URL van de post-editor, bijvoorbeeld post.php?post=123). Bezoek dan rechtstreeks https://jouwsite.nl/?p=123. Laadt die de post, dan is de content prima en zit het probleem in de rewrite-laag: door naar oorzaak 1, 3, 4 of 5. Geeft die óók 404, dan is de post zelf weg: check de prullenbak, check de publicatiestatus en check de slug. Je weet dat deze check klaar is als: je met zekerheid kunt zeggen "de ?p= versie laadt" of "de ?p= versie geeft ook 404".
Check 2: geeft maar één URL 404, of alles? Probeer de homepage, een paar andere gepubliceerde posts en een pagina. Werkt alles behalve die ene URL, dan is oorzaak 2 (post verplaatst of offline) het meest waarschijnlijk. Geeft elke mooie URL behalve de homepage 404, dan is de rewrite-laag weg en kijk je naar oorzaak 1, 3, 4 of 5. Je weet dat deze check klaar is als: je de scope kunt beschrijven ("alleen deze URL" of "alles behalve de homepage").
Check 3: welke server draait de site? Open een terminal of het hostingpaneel en zoek uit of het Apache of nginx is. Op Apache bepaalt dit of oorzaak 3 relevant is. Op nginx ga je rechtstreeks naar oorzaak 4. Zit je op managed hosting en weet je het niet? Kijk naar de response headers: curl -I https://jouwsite.nl/ toont een Server: header met nginx, Apache of LiteSpeed. Je weet dat deze check klaar is als: je de webserver kunt benoemen.
Check 4: staat .htaccess er nog fatsoenlijk uit (alleen Apache)? Open via SFTP of de file manager van je host de root van de site en zoek .htaccess. Zet verborgen bestanden aan. Open het bestand en controleer of het standaard WordPress-blok erin staat, zoals de WordPress httpd-documentatie het voorschrijft:
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
Staat het bestand er niet, of ontbreekt dit blok, dan heb je oorzaak 3 te pakken. Je weet dat deze check klaar is als: je ofwel het standaardblok in het bestand ziet, ofwel hebt vastgesteld dat het ontbreekt.
Check 5: is het een multisite? Kijk in wp-config.php of je define( 'MULTISITE', true ); en define( 'SUBDOMAIN_INSTALL', false ); ziet staan. Staan ze er allebei, dan is het een subdirectory multisite en komt oorzaak 5 in beeld. Je weet dat deze check klaar is als: je "ja, subdirectory multisite" of "nee, gewone single-site" kunt zeggen.
Oplossingen per oorzaak
Oorzaak #1: permalinks opnieuw opslaan en rewrite rules regenereren
Dit is de fix die in zo'n 70% van de gevallen werkt, en hij kost vijf seconden. Log in op wp-admin, ga naar Instellingen → Permalinks, en klik op Wijzigingen opslaan zonder iets te veranderen. Die actie triggert flush_rewrite_rules(), wat de rewrite-cache opnieuw opbouwt vanuit alle geregistreerde regels, en op Apache wordt ook het WordPress-blok in .htaccess opnieuw weggeschreven als het bestand beschrijfbaar is. Je hoeft geen enkele dropdown aan te raken. WordPress kijkt alleen of het formulier is ingediend.
Staat de knop Wijzigingen opslaan grijs? Kies dan even een andere permalink-structuur, sla op, en zet hem daarna terug naar je echte structuur en sla opnieuw op. Het gaat erom dat de save-handler een keer draait.
Verificatie: bezoek de URL die 404 gaf. Die hoort nu te laden. De rij rewrite_rules in wp_options is weer gevuld, en op Apache zie je dat de modified time van .htaccess is bijgewerkt.
Oorzaak #2: post terugzetten, slug corrigeren of redirect aanmaken
Als de ?p=123 check liet zien dat de content echt weg is, zoek dan uit welke van de drie scenario's het was. Staat de post in de prullenbak? Haal hem terug. Is hij offline gehaald? Publiceer hem weer. Is de slug aangepast en krijgt de oude URL nog bezoekers? Maak dan een 301-redirect van het oude pad naar het nieuwe, bijvoorbeeld met een plugin als Redirection, of rechtstreeks in je serverconfig als je liever geen plugin installeert.
Heeft één specifieke URL geen opvolger op de site? Dan kun je de 404 gewoon laten staan, of juist een 410 (Gone) teruggeven zodat zoekmachines de URL sneller uit hun index halen. Dat doet WordPress niet standaard. Een redirect-plugin of een kleine wp_safe_redirect() snippet kan het wel.
Verificatie: de URL laadt de herstelde post, redirect naar de juiste bestemming, of geeft bewust een 404/410 zonder dat er een matching post in de database staat.
Oorzaak #3: .htaccess opnieuw genereren of aanmaken (alleen Apache)
Liet check 4 zien dat het bestand ontbreekt of dat het WordPress-blok eruit is? Dan is de snelste fix: laat WordPress het bestand zelf opnieuw schrijven. Ga naar Instellingen → Permalinks en klik op Wijzigingen opslaan. WordPress schrijft een vers blok als het schrijfrechten heeft op het bestand. Bestaat .htaccess wel, maar is het niet beschrijfbaar? De WordPress file permissions-documentatie noemt 644 als aanbevolen waarde, en geeft aan dat 666 werkt als je wilt dat WordPress het bestand automatisch bijwerkt bij een permalink-save, al is dat minder veilig dan de wijzigingen handmatig synchroniseren.
Kun je wp-admin zelf niet bereiken omdat dat ook 404 geeft? Maak het bestand dan handmatig aan in de site-root. Plak het standaard WordPress-blok uit check 4 erin, sla op en upload het. Dat herstelt de rewrite-laag, waarna je weer in kunt loggen.
Plak .htaccess niet uit een Windows-teksteditor zonder te controleren of de regeleindes Unix zijn. Een .htaccess met CRLF-regeleindes kan in stilte falen en je diagnose flink in de war schoppen.
Verificatie: de URL die 404 gaf laadt weer, en als je .htaccess via SFTP opent zie je het WordPress-blok bovenaan.
Oorzaak #4: nginx of Apache config fixen
Op nginx: voeg de try_files directive toe, of corrigeer hem, in het location / blok volgens de WordPress nginx-richtlijnen:
location / {
try_files $uri $uri/ /index.php?$args;
}
Herlaad nginx (op de meeste Linux-hosts met sudo systemctl reload nginx) en test opnieuw. Voor een config-reload is geen restart nodig.
Op Apache: controleer of mod_rewrite aanstaat (sudo a2enmod rewrite op Debian/Ubuntu) en of de vhost AllowOverride All heeft (of op zijn minst AllowOverride FileInfo) op de WordPress-directory. Zonder AllowOverride negeert Apache .htaccess compleet en wordt het WordPress-blok nooit gelezen. Herlaad Apache na de wijziging.
Zit je op managed hosting, dan kun je die bestanden meestal niet zelf bewerken. Stuur je host de exacte foutmelding en vraag of ze try_files (nginx) of mod_rewrite + AllowOverride (Apache) willen controleren.
Verificatie: alle mooie URL's laden, niet alleen de URL die je aan het testen was. In de access log van de server zie je 200-statussen waar eerst 404 stond.
Oorzaak #5: multisite rewrite-blok herstellen
Voor een subdirectory multisite op Apache is het standaardblok anders dan voor een single-site. WordPress genereert het juiste blok in Netwerk-admin → Instellingen → Netwerk instellen. Open die pagina, kopieer de voorgestelde .htaccess regels en vervang het bestaande WordPress-blok in je site-root. Op nginx toont dezelfde Network Setup-pagina het bijbehorende server block. Gebruik deze uitvoer als bron, omdat hij is gegenereerd voor jouw specifieke installatiepad.
Sla daarna in een willekeurige subsite de permalinks opnieuw op, zodat ook de rewrite-cache in de database wordt ververst.
Verificatie: een pagina bezoeken op elke subsite in het netwerk laadt de pagina, geen 404 meer.
Wanneer hulp vragen
Lossen de stappen hierboven het probleem niet binnen 20 minuten op? Geef het dan door aan je host of een developer, met dit lijstje klaar. Dat scheelt een extra ronde en stuurt het ticket direct naar de juiste engineer:
- De exacte URL die 404 geeft en of de
?p=123versie van dezelfde post wél laadt. - De scope: één URL, één categorie, alle mooie URL's of de hele site.
- Je stack: Apache of nginx, PHP-versie, WordPress-versie, multisite ja of nee.
- Wat er in de laatste 48 uur is veranderd: plugin-updates, theme-updates, core-updates, migraties, serverwijzigingen.
- Of Instellingen → Permalinks → Wijzigingen opslaan überhaupt iets verandert.
- Op Apache: of
.htaccessbestaat en het standaard WordPress-blok bevat. - Op nginx: of het site-block
try_files $uri $uri/ /index.php?$args;heeft. - De relevante regels uit de access log van de server rond het tijdstip van de 404's (zoek op de 404-status en de URL).
Op een goed geconfigureerde host is een 404 op een gepubliceerde pagina die gewoon in het dashboard staat een fix van vijf minuten. Duurt het langer, dan zit het probleem meestal in de rewrite-laag, niet in de post, en de informatie hierboven wijst precies aan in welke laag.
Hoe je voorkomt dat het terugkomt
Drie gewoontes houden rewrite-gerelateerde 404's zeldzaam op een gezonde site:
- Sla na elke migratie direct de permalinks opnieuw op. Een migratie verplaatst bestanden en database, maar de rewrite-cache in
wp_optionsen het.htaccessbestand lopen daarna vaak niet meer in de pas met het nieuwe installatiepad. Eén extra klik op Wijzigingen opslaan direct na de migratie vangt het merendeel van dit soort problemen voordat een bezoeker er last van heeft. - Houd je permalink-structuur stabiel. Elke keer dat de structuur verandert, breken bestaande inbound links, tenzij je redirects toevoegt. Het beste moment om een permalink-structuur te kiezen is de dag dat je de site live zet. Het slechtste moment is de dag na een geslaagde campagne.
- Zet
.htaccessin versiebeheer als je het met de hand bewerkt. Draait je site op Apache en heb je custom rewrite rules? Houd.htaccessdan bij in een git-repo naast de rest van je deploy. Een.htaccessdat door Instellingen → Permalinks opnieuw is gegenereerd is herstelbaar. Een handmatig bewerkte variant die door een plugin is overschreven is dat niet.
404's die uit de rewrite-laag komen zijn irritant omdat het lijkt alsof je content weg is. Dat is het bijna nooit. De content staat nog in de database, de URL is geregistreerd, en het enige dat stuk is, is de koppeling tussen die twee. De vijf fixes hierboven bouwen die koppeling opnieuw op.