Actualitzar WordPress hauria de ser una tasca rutinària. Amb còpia de seguretat, revisió prèvia i un mínim de control, no hauria de convertir-se en una tarda de pànic. Però de vegades passa.
Fa poc, després d’actualitzar un web d’un client a WordPress 7, la pàgina va començar a retornar un error 403 Forbidden. De primeres, la sospita era força lògica: «Ha estat actualitzar WordPress i el web s’ha trencat.»
Però no. El problema no era WordPress 7.
El problema estava en una regla de l’arxiu .htaccess que bloquejava l’accés a un arxiu que WordPress necessitava utilitzar durant el procés d’actualització: upgrade.php.
I em sembla un cas molt interessant per explicar, perquè resumeix molt bé alguna cosa que veig sovint en manteniment WordPress: una mesura de seguretat mal plantejada pot acabar trencant just allò que intenta protegir.
💥 Què va passar després d’actualitzar a WordPress 7
El símptoma era clar: després d’actualitzar WordPress, el web retornava un error 403.
Un 403 significa, simplificant molt, que el servidor ha entès la petició, però no permet accedir al recurs sol·licitat. No és exactament el mateix que un error 500, on sol haver-hi una fallada interna d’execució, ni que un 404, on el recurs no es troba.
Aquí el servidor deia alguna cosa així com: «Sé el que em demanes, però no et deixo passar.»
Quan això passa just després d’actualitzar WordPress, és normal pensar que l’actualització ha provocat la fallada. De fet, en la meva guia sobre com actualitzar WordPress i plugins sense trencar res ja insisteixo molt en això: actualitzar és necessari, però no cal fer-ho a cegues.
Ara bé, una cosa és que l’error aparegui després d’actualitzar i una altra molt diferent és que l’actualització sigui la causa real.
En aquest cas, WordPress 7 només va ser el detonant. La causa ja hi era abans.
🚫 Per què un error 403 a WordPress pot tenir diverses causes
Abans de tocar res, el important era no assumir massa ràpid.
Un error 403 a WordPress pot venir de molts llocs:
- permisos incorrectes en arxius o carpetes
- regles massa agressives al
.htaccess - bloqueig de ModSecurity o del firewall de l’hosting
- un plugin de seguretat
- una regla de CDN, per exemple Cloudflare
- protecció específica sobre
/wp-admin/ - arxius del core bloquejats per error
Per això, quan algú em diu «no puc accedir a WordPress», no vaig directe a esborrar plugins o canviar coses sense criteri. De fet, aquest cas connecta molt bé amb un altre article on explico què revisar quan no pots accedir a WordPress.

La clau és anar descartant capes. Primer cal saber si el bloqueig ve de WordPress, del servidor, del .htaccess, d’un plugin o de l’hosting.
🔍 Les proves que vaig fer per acotar el problema
El procés va ser força senzill, però molt útil.
Primer vaig comprovar si l’error afectava tot el web o només zones concretes:
- /
- /wp-admin/
- /wp-login.php
- /wp-json/
- /wp-admin/upgrade.php
Això ajuda molt, perquè si tot el web retorna 403, sol mirar primer permisos, .htaccess, regles del servidor o WAF.
Però si l’error apareix en accedir a l’admin, en actualitzar la base de dades o en una URL concreta, llavors convé buscar una regla que estigui bloquejant aquella ruta o aquell arxiu.
I aquí va aparèixer la pista clau: WordPress, després de certes actualitzacions, pot necessitar executar una actualització de base de dades des d’una URL com: /wp-admin/upgrade.php
La pròpia documentació oficial de WordPress sobre actualitzacions explica que, si cal actualitzar la base de dades després d’una actualització, WordPress et pot portar a una URL d’aquest tipus: wp-admin/upgrade.php.
Per tant, el següent pas era evident: revisar el .htaccess.
⚙️ La regla del .htaccess que provocava el 403
Dins del .htaccess hi havia un bloc de protecció per a arxius no públics de WordPress. La intenció era bona: evitar que certs arxius sensibles o innecessaris fossin accessibles des del navegador.
El problema estava en aquesta part:
<FilesMatch "^(install\.php|upgrade\.php|license\.txt|licencia\.txt|readme\.html|debug_log|error_log|access_log)$">
Require all denied
</FilesMatch>
A simple vista pot semblar una regla raonable. Però no ho era.
El problema concret estava aquí: upgrade.php. Aquesta regla impedia l’accés a qualsevol arxiu anomenat upgrade.php. I com que WordPress pot necessitar carregar: /wp-admin/upgrade.php el servidor responia amb un 403.
És a dir, WordPress intentava completar el seu flux normal d’actualització, però Apache el bloquejava abans que WordPress pogués fer res.
La documentació d’Apache sobre FilesMatch deixa clar que aquesta directiva aplica regles als arxius el nom dels quals coincideix amb l’expressió indicada. En aquest cas, l’expressió coincidia massa bé: bloquejava just l’arxiu que WordPress necessitava.
🔓 Per què upgrade.php no s’hauria de bloquejar així
Aquest és el punt important. upgrade.php pot semblar un arxiu delicat. I en cert mode ho és. Però això no vol dir que calgui bloquejar-lo globalment des del .htaccess.

A WordPress, no tot arxiu que «sembla sensible» ha de ser inaccessible sempre.
Hi ha arxius que el propi core pot necessitar en moments concrets. I si els bloqueges des d’Apache, WordPress ni tan sols arriba a decidir què fer: el servidor talla la petició abans.
Això va ser exactament el que va passar aquí. L’error no venia de WordPress 7. L’error venia d’una regla massa agressiva.
I aquest matís és important, perquè sovint veig configuracions de seguretat copiades d’internet que afegeixen capa rere capa de bloqueig sense valorar el context real del lloc.
Protegir un web no és posar moltes regles. Protegir un web és posar les regles correctes.
✅ Com vaig corregir la regla
La solució va ser treure upgrade.php d’aquest bloqueig. També vaig aprofitar per simplificar la regla i deixar-la centrada en arxius que sí té sentit protegir de forma permanent.
La versió problemàtica era aquesta:
<FilesMatch "^(install\.php|upgrade\.php|license\.txt|licencia\.txt|readme\.html|debug_log|error_log|access_log)$">
Require all denied
</FilesMatch>
I la versió corregida va quedar així:
<FilesMatch "^(license\.txt|licencia\.txt|readme\.html|debug_log|error_log|access_log)$">
Require all denied
</FilesMatch>
Amb aquest canvi, WordPress va poder tornar a accedir a wp-admin/upgrade.php i completar el procés.
Després d’això, convé fer les comprovacions habituals:
- /wp-admin/
- /wp-admin/upgrade.php
- /wp-login.php
- /wp-json/
I, si tot és correcte, entrar al panell i desar de nou els enllaços permanents des de: Configuració > Enllaços permanents > Desa els canvis
També és bona idea purgar la memòria cau si s’utilitza WP Rocket, LiteSpeed Cache, Cloudflare o qualsevol sistema similar.
⚠️ Compte amb bloquejar arxius comprimits des del .htaccess
En aquest cas concret, el problema era upgrade.php. Però ja que revisava el .htaccess, hi havia una altra regla que mereixia atenció:
<FilesMatch "\.(bak|old|orig|save|sql|zip|tar|gz)$">
Require all denied
</FilesMatch>
Bloquejar arxius .bak, .old, .orig, .save o .sql té sentit. Però bloquejar sempre .zip, .tar o .gz et pot donar problemes segons com treballi el teu sistema de memòria cau, còpies de seguretat, descàrregues o desplegaments. No dic que calgui permetre’ls sempre. Dic que no convé posar-los en una regla global sense pensar què fa exactament aquest web.
Una alternativa més prudent seria:
<FilesMatch "\.(bak|old|orig|save|sql)$">
Require all denied
</FilesMatch>
I si cal protegir còpies de seguretat o paquets concrets, prefereixo fer-ho en una carpeta específica, no bloquejant extensions de forma indiscriminada en tota la instal·lació.
🔧 El .htaccess pot arreglar un web… o trencar-lo
El .htaccess és un d’aquests arxius que semblen petits, però poden tirar avall un web sencer. Serveix per gestionar redireccions, enllaços permanents, capçaleres, memòria cau, compressió, regles de seguretat i moltes altres coses. Però precisament per això cal tractar-lo amb respecte.
En altres errors, com l’error 500 a WordPress, el .htaccess també sol aparèixer com a sospitós habitual. Una regla mal escrita, una directiva no suportada per l’hosting o un bloqueig excessiu poden generar errors molt diferents.
En aquest cas no va ser un 500. Va ser un 403. Però la lògica era la mateixa: una regla del servidor interferia amb el comportament normal de WordPress.
💡 El més interessant del cas: WordPress 7 no en tenia la culpa
Per a mi, aquesta és la part més important del cas. L’actualització a WordPress 7 no va trencar el web per si sola. El que va fer va ser posar al descobert una configuració incorrecta que ja hi era. I això passa sovint.

Un web pot funcionar aparentment bé durant mesos o anys amb una configuració fràgil. Fins que un dia actualitzes WordPress, canvies PHP, actualitzes un plugin, actives una memòria cau, migres d’hosting o modifiques una regla de seguretat.
Llavors apareix l’error. I és molt fàcil culpar l’últim canvi. Però en manteniment WordPress, culpar l’últim canvi sense investigar és una mala pràctica. L’últim canvi pot ser la causa. O pot ser només el detonant. Aquí va ser el segon.
📋 Què faria abans d’actualitzar un web crític
Aquest cas reforça alguna cosa que aplico sempre que un web té certa importància comercial. Abans d’actualitzar WordPress, plugins o tema, convé tenir com a mínim:
1. Còpia de seguretat recent i restaurable
No n’hi ha prou amb «tenir còpies de seguretat». Cal saber si es poden restaurar. Sembla obvi, però quan un web falla, descobrir que la còpia de seguretat no serveix és una faena seriosa.
2. Revisió de plugins, tema i versió de PHP
No tot conflicte ve del core. Sovint el problema real està en un plugin abandonat, una plantilla antiga o una versió de PHP que ja no encaixa.
3. Control del .htaccess
No cal revisar cada línia en cada actualització menor, però si un web té regles personalitzades de seguretat, redireccions o memòria cau, cal saber què fan.
Copiar regles sense entendre-les és una mala estratègia.
4. Proves després d’actualitzar
No n’hi ha prou amb veure que la home carrega. Després d’una actualització important, reviso com a mínim:
- Home
- /wp-admin/
- login
- formularis
- checkout si hi ha WooCommerce
- cercador
- pàgines clau
- REST API
- sitemap
- consola del navegador
- logs d’errors
5. Mètode per aïllar l’error
Si alguna cosa falla, no es tracta de tocar deu coses alhora. Es tracta de provar per capes: plugins, tema, .htaccess, permisos, memòria cau, WAF, servidor i logs.
🛡️ La bona regla: menys «seguretat decorativa» i més criteri
M’agrada reforçar això perquè és una font habitual de problemes.
Hi ha moltes recomanacions de seguretat per a WordPress que es copien sense context:
- Bloqueja aquest arxiu
- Desactiva aquesta ruta
- Afegeix aquesta regla
- Amaga això
- Denega allò
Algunes són útils. Altres són innecessàries. I algunes, directament, poden trencar funcionalitats legítimes.
La seguretat no hauria de ser una col·lecció de regles enganxades al .htaccess. Hauria de ser una combinació de:
- actualitzacions controlades
- còpies de seguretat fiables
- permisos correctes
- monitorització
- firewall ben configurat
- contrasenyes i accessos segurs
- plugins mantinguts
- criteri tècnic
Una regla que bloqueja upgrade.php pot semblar protectora, però si impedeix que WordPress actualitzi la base de dades després d’una actualització, acaba sent un problema.
✔️ Conclusió: no era WordPress 7, era una mala regla
Aquest cas va començar com molts altres: «He actualitzat WordPress i ara el web dona error.» Però va acabar amb una conclusió força diferent: «L’actualització ha posat al descobert una regla del .htaccess que no hauria d’estar bloquejant upgrade.php.»
La solució no va ser desfer WordPress 7. Tampoc va ser desactivar tots els plugins a lo boig. Ni restaurar una còpia sense investigar. La solució va ser diagnosticar, acotar i corregir la regla exacta que provocava el 403. I aquesta és la diferència entre apagar foc i mantenir un web amb criteri.
🆘 Vols evitar que una actualització acabi en una caiguda?
Si el teu web WordPress genera contactes, vendes o reserves, no hauries de dependre d’actualitzacions improvisades ni de regles copiades sense revisar.
En el meu servei de manteniment WordPress professional m’encarrego de revisar, actualitzar, monitoritzar i resoldre aquest tipus d’incidències amb mètode, no a base de prova i error.
Perquè mantenir WordPress no és prémer el botó d’actualitzar. És assegurar-se que, quan alguna cosa canvia, el web segueix funcionant com ha de fer.