Vai al contenuto
Server e .htaccess

Gli articoli WordPress restituiscono un 404 ma la homepage funziona

Se la homepage si carica senza problemi ma ogni singolo articolo e pagina restituisce un 404, le regole di riscrittura degli URL su cui WordPress fa affidamento sono mancanti o danneggiate nel tuo

Pubblicato

Se la homepage si carica senza problemi ma ogni singolo articolo e pagina restituisce un 404, le regole di riscrittura degli URL su cui WordPress fa affidamento sono mancanti o danneggiate nel tuo file .htaccess. La soluzione più rapida: vai su Impostazioni → Permalink in wp-admin e clicca su Salva le modifiche senza cambiare nulla. Questo costringe WordPress a rigenerare il blocco di riscrittura. Se i 404 persistono, il tuo .htaccess non è scrivibile dal web server, Apache è configurato per ignorarlo, oppure sei su Nginx (che non usa affatto .htaccess).

Perché la homepage funziona ma gli articoli no

La tua homepage funziona perché una richiesta a / viene servita direttamente da index.php nella root del sito. Non serve alcuna riscrittura.

Una richiesta a /2026/il-mio-articolo/ è diversa. Quel percorso non è una cartella reale sul disco. Perché WordPress possa rispondere, Apache deve instradare internamente la richiesta a index.php, e WordPress a quel punto legge REQUEST_URI, lo confronta con le regole di riscrittura salvate nell’opzione rewrite_rules del database, risolve le query vars (WP::parse_request()) e carica l’articolo giusto.

Il passaggio da Apache a index.php è la parte che si rompe. Dipende interamente da questo blocco nel .htaccess:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Le due righe RewriteCond dicono: se il percorso richiesto non è un file reale (!-f) e non è una directory reale (!-d), invialo a index.php. Rimuovi quel blocco e Apache cerca una directory letterale /2026/il-mio-articolo/, non la trova e restituisce il proprio 404 — prima ancora che WordPress veda la richiesta.

Questa è la parte che la maggior parte delle guide salta. Quando clicchi su Salva nella schermata dei Permalink, WordPress chiama flush_rewrite_rules(). Su Apache con un .htaccess scrivibile, questo attiva save_mod_rewrite_rules(), che rigenera il blocco qui sopra tramite WP_Rewrite::mod_rewrite_rules() e lo riscrive usando insert_with_markers().

insert_with_markers() tocca solo le righe comprese tra # BEGIN WordPress e # END WordPress. Tutto ciò che sta fuori da quei marcatori viene lasciato intatto. Tutto ciò che sta dentro viene scartato e riscritto. Le versioni più recenti di WordPress stampano perfino l’avviso direttamente nel file:

Any changes to the directives between these markers will be overwritten.

Quindi “WordPress sovrascrive il mio .htaccess” è vero ma con dei limiti: riscrive solo il proprio blocco marcato, e solo quando il file è scrivibile. Se il file non è scrivibile, il salvataggio non fa silenziosamente nulla sul disco. WordPress mostra un avviso giallo nella schermata dei Permalink che ti dice di incollare le regole manualmente, e se non noti quell’avviso, il tuo blocco di riscrittura resta mancante e ogni articolo continua a restituire 404.

Come risolvere, in ordine

1. Ri-salva i tuoi permalink. Impostazioni → Permalink → Salva le modifiche. Non serve modificare nulla. Questo riesegue il flush e riscrive il blocco. Risolve la maggior parte dei casi, incluse le regole obsolete dopo una migrazione.

2. Verifica che .htaccess esista e sia scrivibile. Si trova nella stessa cartella di wp-config.php. È un dotfile, quindi abilita “mostra file nascosti” nel tuo client FTP oppure usa:

ls -la /path/to/wordpress/.htaccess

Se manca, crealo e incolla il blocco corretto. Se la tua installazione si trova in una sottodirectory, RewriteBase e la destinazione finale della riscrittura devono corrispondere a quel percorso — sbagliare questo è il motivo più comune per cui un blocco incollato a mano continua a dare 404. Il nostro generatore di .htaccess crea il blocco esatto per il percorso della tua installazione, così non devi tirare a indovinare.

3. Conferma che Apache possa leggere .htaccess. Se il virtual host ha AllowOverride None, Apache ignora completamente il file a prescindere dal suo contenuto. Ti serve AllowOverride All (o almeno FileInfo) sulla directory di WordPress. Questo si trova nella configurazione del server, non in .htaccess, quindi richiede l’accesso al server:

<Directory /var/www/html>
    AllowOverride All
</Directory>

4. Conferma che mod_rewrite sia abilitato. Su Debian/Ubuntu:

sudo a2enmod rewrite
sudo systemctl restart apache2

5. Su Nginx non esiste alcun .htaccess. Le riscritture vanno invece nel server block:

location / {
    try_files $uri $uri/ /index.php?$args;
}

Diagnosi rapida: di chi è il 404?

Guarda la pagina 404. Se è una pagina di errore di Apache o dell’host senza stile, Apache non ha mai raggiunto WordPress — è un problema di .htaccess o di configurazione del server (passi 2–4). Se è il 404 con lo stile del tuo tema, WordPress sta ricevendo la richiesta ma non riesce ad abbinarla — le regole nel database sono obsolete, e ri-salvare i permalink (passo 1) è la soluzione. Questa singola distinzione fa risparmiare a molti un’ora di tentativi.

Cosa non fare

Non disattivare prima tutti i tuoi plugin. Un sintomo puro di “articoli 404, homepage funzionante” è un problema di riscrittura, non un conflitto tra plugin. Disattivare i plugin è la risposta istintiva sui forum e quasi mai c’entra qualcosa con questo.

Non fare chmod 777 sul tuo .htaccess. WordPress ha bisogno che il file sia scrivibile dall’utente del web server, che non è la stessa cosa di scrivibile da chiunque. 644 con il proprietario corretto va bene ed è sicuro; 777 è una falla di sicurezza che comunque non risolverà il routing.

Non incollare regole di riscrittura personalizzate all’interno dei marcatori # BEGIN WordPress / # END WordPress. Verranno cancellate la prossima volta che qualcuno salva i permalink. Metti le direttive personalizzate sopra la riga # BEGIN WordPress.

Non reinstallare WordPress. I file del core sono a posto. Si tratta di un unico blocco di testo mancante, non di un’installazione corrotta.

Non dare la colpa al tuo tema. Il routing dei permalink è parte del core di WordPress. Un tema non può causarlo e non può risolverlo.

Ancora bloccato?

Se hai ri-salvato i permalink, confermato che il blocco è presente e scrivibile e impostato AllowOverride All, il sospettato che rimane è un plugin di sicurezza o una regola a livello di host che rigenera o blocca .htaccess a tua insaputa. Controlla il timestamp di modifica del file subito dopo un salvataggio dei permalink — se non è cambiato, qualcosa sta bloccando la scrittura. Rigenera un blocco pulito con il generatore di .htaccess, incollalo e riprova con un refresh forzato.