Posts do WordPress retornam 404, mas a página inicial funciona
Se a sua página inicial carrega normalmente, mas cada post e página individual retorna um 404, as regras de reescrita de URL das quais o WordPress depende estão faltando ou quebradas no seu
Publicado
Se a sua página inicial carrega normalmente, mas cada post e página individual retorna um 404, as regras de reescrita de URL das quais o WordPress depende estão faltando ou quebradas no seu arquivo .htaccess. A correção mais rápida: vá em Configurações → Links permanentes no wp-admin e clique em Salvar alterações sem mudar absolutamente nada. Isso força o WordPress a regenerar o bloco de reescrita. Se os 404 persistirem, é porque o seu .htaccess não pode ser gravado pelo servidor web, o Apache está configurado para ignorá-lo, ou você está no Nginx (que não usa .htaccess de forma alguma).
Por que a página inicial funciona, mas os posts não
A sua página inicial funciona porque uma requisição para / é servida diretamente pelo index.php na raiz do site. Nenhuma reescrita é necessária.
Uma requisição para /2026/meu-post/ é diferente. Esse caminho não é uma pasta real no disco. Para o WordPress respondê-la, o Apache precisa rotear internamente a requisição para o index.php, e o WordPress então lê o REQUEST_URI, compara-o com as regras de reescrita armazenadas na opção rewrite_rules no banco de dados, resolve as query vars (WP::parse_request()) e carrega o post correto.
A passagem do Apache para o index.php é a parte que quebra. Ela depende inteiramente deste bloco no .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
As duas linhas RewriteCond dizem: se o caminho requisitado não for um arquivo real (!-f) e não for um diretório real (!-d), envie-o para o index.php. Remova esse bloco e o Apache vai procurar por um diretório literal /2026/meu-post/, não vai encontrar e retorna o próprio 404 dele — antes mesmo de o WordPress ver a requisição.
Por que o WordPress sobrescreve o .htaccess quando você salva os links permanentes
Essa é a parte que a maioria dos guias pula. Quando você clica em Salvar na tela de Links permanentes, o WordPress chama flush_rewrite_rules(). No Apache com um .htaccess gravável, isso dispara o save_mod_rewrite_rules(), que regenera o bloco acima via WP_Rewrite::mod_rewrite_rules() e o grava de volta usando insert_with_markers().
O insert_with_markers() só mexe nas linhas entre # BEGIN WordPress e # END WordPress. Tudo o que está fora desses marcadores fica intocado. Tudo o que está dentro é descartado e reescrito. Versões mais recentes do WordPress até imprimem o aviso diretamente no arquivo:
Any changes to the directives between these markers will be overwritten.
Então “o WordPress sobrescreve meu .htaccess” é verdade, mas de forma limitada: ele só reescreve o próprio bloco marcado, e apenas quando o arquivo é gravável. Se o arquivo não for gravável, o salvamento silenciosamente não faz nada no disco. O WordPress mostra um aviso amarelo na tela de Links permanentes dizendo para você colar as regras manualmente, e se você não perceber esse aviso, o seu bloco de reescrita continua faltando e cada post continua retornando 404.
Como corrigir, em ordem
1. Salve os links permanentes de novo. Configurações → Links permanentes → Salvar alterações. Nenhuma edição necessária. Isso executa o flush de novo e reescreve o bloco. Resolve a maioria dos casos, incluindo regras desatualizadas após uma migração.
2. Verifique se o .htaccess existe e é gravável. Ele fica na mesma pasta que o wp-config.php. É um dotfile, então habilite “mostrar arquivos ocultos” no seu cliente FTP ou use:
ls -la /path/to/wordpress/.htaccess
Se ele estiver faltando, crie-o e cole o bloco correto. Se a sua instalação estiver em um subdiretório, o RewriteBase e o alvo final da reescrita precisam corresponder a esse caminho — errar isso é o motivo mais comum de um bloco colado à mão ainda dar 404. Nosso gerenciador do .htaccess monta o bloco exato para o caminho da sua instalação, para você não ter que adivinhar.
3. Confirme que o Apache tem permissão para ler o .htaccess. Se o virtual host tiver AllowOverride None, o Apache ignora o arquivo completamente, independentemente do conteúdo. Você precisa de AllowOverride All (ou pelo menos FileInfo) no diretório do WordPress. Isso fica na configuração do servidor, não no .htaccess, então exige acesso ao servidor:
<Directory /var/www/html>
AllowOverride All
</Directory>
4. Confirme que o mod_rewrite está habilitado. No Debian/Ubuntu:
sudo a2enmod rewrite
sudo systemctl restart apache2
5. No Nginx, não existe .htaccess. As reescritas vão no server block, em vez disso:
location / {
try_files $uri $uri/ /index.php?$args;
}
Diagnóstico rápido: de quem é o 404?
Olhe a página de 404. Se for uma página de erro sem estilo do Apache ou da hospedagem, o Apache nunca chegou ao WordPress — isso é um problema de .htaccess ou de configuração do servidor (passos 2 a 4). Se for o 404 estilizado do seu tema, o WordPress está recebendo a requisição, mas não consegue fazer a correspondência — as regras no banco de dados estão desatualizadas, e salvar os links permanentes de novo (passo 1) é a correção. Essa única distinção economiza uma hora de tentativa e erro para a maioria das pessoas.
O que não fazer
Não desative todos os seus plugins primeiro. Um sintoma puro de “posts em 404, página inicial funciona” é um problema de reescrita, não um conflito de plugin. Desativar plugins é a resposta reflexa nos fóruns, e quase nunca tem a ver com isso.
Não faça chmod 777 no seu .htaccess. O WordPress precisa que o arquivo seja gravável pelo usuário do servidor web, o que não é a mesma coisa que gravável por todos. 644 com o dono correto é adequado e seguro; 777 é uma brecha de segurança que, de qualquer forma, não vai corrigir o roteamento.
Não cole regras de reescrita personalizadas dentro dos marcadores # BEGIN WordPress / # END WordPress. Elas serão apagadas na próxima vez que alguém salvar os links permanentes. Coloque as diretivas personalizadas acima da linha # BEGIN WordPress.
Não reinstale o WordPress. Os arquivos do core estão bem. Isso é um único bloco de texto faltando, não uma instalação corrompida.
Não culpe o seu tema. O roteamento de links permanentes é core do WordPress. Um tema não pode causá-lo nem corrigi-lo.
Ainda travado?
Se você já salvou os links permanentes de novo, confirmou que o bloco está presente e gravável e definiu AllowOverride All, o suspeito restante é um plugin de segurança ou uma regra a nível de hospedagem regenerando ou travando o .htaccess pelas suas costas. Verifique o timestamp de modificação do arquivo logo após salvar os links permanentes — se ele não mudou, algo está bloqueando a gravação. Regenere um bloco limpo com o gerenciador do .htaccess, cole-o e teste de novo com um hard refresh.