WordPress

    Ana Sayfa Açılıyor Ama Yazılar 404 Veriyor: Neden ve Çözüm

    Yalnızca iç sayfaların 404 verdiği durumda yönlendirme kurallarının nerede koptuğunu bulmak.

    12 dk okuma Güncellendi: 11 Ağustos 2026

    WordPress'te yazılar 404 veriyor ama ana sayfa sorunsuz açılıyorsa, elinizde aslında çok değerli bir ipucu var. Bu tablo neredeyse hiçbir zaman "site çöktü" anlamına gelmez; PHP çalışıyor, veritabanı bağlanıyor, tema yükleniyor demektir. Kopan tek şey, güzel adreslerin (kalıcı bağlantıların) doğru dosyaya yönlendirilmesidir. Yani sunucu https://ornek.com/blog/ilk-yazim/ isteğini alıyor, bunu gerçek bir klasör sanıyor, bulamıyor ve 404 dönüyor — WordPress'in devreye girmesine hiç fırsat vermeden.

    Türkçe kaynakların tamamına yakını bu noktada tek bir şey söyler: Ayarlar → Kalıcı Bağlantılar'a girip Kaydet'e basın. Bu adım gerçekten de vakaların bir bölümünü çözer, ama işe yaramadığında ne yapacağınızı kimse anlatmaz. Bu yazıda kalıcı bağlantı sıfırlamanın neden bazen hiçbir şey değiştirmediğini, .htaccess yazılabilir değilse ne olduğunu, Apache'de mod_rewrite ve AllowOverride ayarlarının nasıl kontrol edileceğini ve — Türkçe'de neredeyse hiç ele alınmayan kısım — Nginx'te try_files kuralı hiç tanımlanmamışsa sorunun nasıl çözüleceğini sırayla göstereceğim. VDS kullanan okurların çoğu Nginx'te olduğu için o bölümü tam bir yapılandırma örneğiyle veriyorum.

    Neden Sadece İç Sayfalar 404 Veriyor#

    Ana sayfanın açılıp iç sayfaların açılmaması tesadüf değildir, mimarinin doğal sonucudur. Ana sayfa isteği https://ornek.com/ adresine gelir; web sunucusu bu isteği kök dizindeki index.php dosyasına götürür ve WordPress çalışır. İç sayfa isteği ise https://ornek.com/hizmetlerimiz/ biçimindedir. Sunucu bunu önce gerçek bir dosya ya da klasör olarak arar. Böyle bir klasör yoktur — çünkü WordPress sayfaları diskte klasör olarak tutmaz, veritabanında satır olarak tutar.

    İşte bu noktada devreye bir yönlendirme kuralı girmesi gerekir. Bu kural sunucuya şunu söyler: "Böyle bir dosya ya da klasör bulamazsan isteği index.php'ye gönder, gerisini WordPress halleder." Kural yoksa, bozuksa ya da sunucu tarafından okunmuyorsa sunucu isteği kendi başına sonlandırır ve 404 döner.

    Bu yüzden bir ayrım hemen yapılabilir: 404 sayfası WordPress temanızın tasarımıyla mı geliyor, yoksa çıplak bir sunucu sayfası mı?

    • Sayfada sitenizin menüsü, logosu, "Aradığınız sayfa bulunamadı" yazısı temanızın stiliyle görünüyorsa: kural çalışıyor, istek WordPress'e ulaşıyor. Sorun kalıcı bağlantı yapısında değil, içerikte ya da veritabanındadır.
    • Sayfada beyaz zeminde "Not Found — The requested URL was not found on this server" ya da Nginx'in koyu gri "404 Not Found" ekranı varsa: istek WordPress'e hiç ulaşmıyor. Sorun sunucu yönlendirme kuralındadır.

    Bu tek ayrım, aşağıdaki bölümlerin hangisini okuyacağınızı belirler. HTTP durum kodunun genel anlamı ve diğer bağlamları için 404 not found hatası çözümü yazısına da bakabilirsiniz.

    Adım 1: Kalıcı Bağlantıları Sıfırlama#

    En hızlı ve zararsız adım budur, önce onu deneyin. Yönetim panelinde Ayarlar → Kalıcı Bağlantılar ekranına girin ve hiçbir şeyi değiştirmeden Değişiklikleri Kaydet düğmesine basın.

    Bu düğme göründüğünden fazlasını yapar: WordPress kural setini yeniden üretir ve Apache ortamında bunu .htaccess dosyasına yazmayı dener. Kural bozulduysa, dosya silindiyse ya da bir eklenti araya kural sıkıştırıp yapıyı bozduysa bu işlem düzeltir.

    Beklenen .htaccess içeriği tam olarak şudur:

    # 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
    

    Kaydettikten sonra sayfayı açın. Düzeldiyse iş bitmiştir. Düzelmediyse şu iki ihtimalden biri geçerlidir: dosya yazılamıyordur ya da sunucu bu dosyayı hiç okumuyordur. İkisini de aşağıda ayırıyoruz. Kalıcı bağlantı yapısını seçme ve SEO açısından hangisinin uygun olduğu konusunda wordpress permalink ayarları yazısı ayrı bir referanstır.

    Adım 2: Sunucunuz Apache mi Nginx mi#

    Bundan sonraki her adım sunucu yazılımına göre değişir, o yüzden önce bunu kesinleştirin. En hızlı yol yanıt başlıklarına bakmaktır:

    curl -sI https://ornek.com/ | grep -i "^server:"
    
    server: nginx
    

    Yanıt nginx ise Nginx bölümüne, Apache ise Apache bölümüne gidin. LiteSpeed görüyorsanız Apache kurallarını okuyun; LiteSpeed .htaccess dosyasını okur ve büyük ölçüde uyumludur. cloudflare görüyorsanız başlık ara katmandan geliyordur; gerçek sunucuyu öğrenmek için sunucunuzun IP'sine doğrudan istek atmanız ya da barındırma panelinize bakmanız gerekir.

    Panelden bakmak isterseniz: cPanel'de sol sütundaki "Genel Bilgiler" bölümünde Apache sürümü yazar. Kendi VDS'inizi yönetiyorsanız zaten hangisini kurduğunuzu bilirsiniz; emin değilseniz systemctl status nginx ve systemctl status apache2 komutlarından hangisi çalışıyorsa odur. İkisinin mimari farkı ve hangi durumda hangisinin tercih edildiği için apache vs nginx karşılaştırmasına göz atabilirsiniz.

    Apache: .htaccess Var mı, Yazılabilir mi#

    Apache kullanıyorsanız 404'ün en yaygın nedeni, .htaccess dosyasının olmaması ya da WordPress tarafından yazılamamasıdır. Kalıcı bağlantıları kaydettiğinizde WordPress sessizce dener; yazamazsa panelin altında küçük bir uyarı gösterir ama bu uyarı çok kolay gözden kaçar.

    Dosyanın varlığını ve iznini kontrol edin (nokta ile başladığı için ls -la gerekir, ls göstermez):

    cd /var/www/ornek.com
    ls -la .htaccess
    
    -rw-r--r-- 1 www-data www-data 235 Aug  2 11:04 .htaccess
    

    Dosya yoksa oluşturun ve yukarıdaki blok içeriğini yapıştırın:

    touch .htaccess
    chown www-data:www-data .htaccess
    chmod 644 .htaccess
    

    Kullanıcı adını kendi sunucunuzdaki PHP kullanıcısıyla değiştirin. cPanel kullanıyorsanız bu işi Dosya Yöneticisi'nden yaparsınız — ayarlar bölümünden "gizli dosyaları göster" seçeneğini işaretlemezseniz .htaccess listede görünmez, bu yüzden birçok kullanıcı dosya yok sanır.

    İçeriği kontrol ederken üç şeye dikkat edin:

    1. # BEGIN WordPress ve # END WordPress bloğu bir kez geçmeli. Eklentiler kendi kurallarını bu bloğun dışına yazar; blok iki kez varsa ikincisini silin.
    2. RewriteBase değeri, WordPress'in kurulu olduğu yolu göstermeli. Kök dizinde /, alt dizinde /blog/ olmalıdır.
    3. Bloğun üstünde başka bir eklentiden kalma ve L bayrağıyla biten bir yönlendirme varsa, WordPress kuralına hiç sıra gelmez. Şüpheleniyorsanız dosyayı .htaccess.yedek olarak yeniden adlandırıp yalnızca standart blokla test edin.

    Kural yazımının mantığını ve bayrakların ne işe yaradığını htaccess yönlendirme yazısında ayrıntılı anlattım.

    Apache: mod_rewrite ve AllowOverride Kontrolü#

    .htaccess yerinde ve içeriği doğru olduğu hâlde 404 devam ediyorsa, sunucu bu dosyayı ya hiç okumuyordur ya da içindeki kuralı işleyecek modül kapalıdır. Bu, kendi sunucusunu kuran kullanıcıların çok sık düştüğü tuzaktır ve Türkçe kaynaklarda genellikle atlanır.

    Önce mod_rewrite etkin mi bakın:

    apache2ctl -M | grep rewrite
    

    Çıktı boşsa modül kapalıdır. Debian/Ubuntu'da açmak için:

    a2enmod rewrite
    systemctl restart apache2
    

    AlmaLinux/CentOS ailesinde modül genellikle /etc/httpd/conf.modules.d/ altında zaten yüklüdür; httpd -M | grep rewrite ile doğrulayın.

    İkinci kontrol AllowOverride ayarıdır. Apache, bir dizinde .htaccess dosyasını yalnızca izin verilmişse okur; varsayılan yapılandırmaların çoğunda bu izin kapalıdır. Sanal sunucu ya da dizin bloğunuza bakın:

    grep -rn "AllowOverride" /etc/apache2/sites-available/ /etc/apache2/apache2.conf
    

    Şu satırı görüyorsanız .htaccess tamamen yok sayılıyordur:

    <Directory /var/www/>
        AllowOverride None
    </Directory>
    

    Doğru hâli:

    <Directory /var/www/ornek.com>
        Options FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    

    Değişiklikten sonra yapılandırmayı sınayıp servisi yeniden yükleyin:

    apache2ctl configtest
    systemctl reload apache2
    

    configtest çıktısı Syntax OK demiyorsa yeniden yüklemeyin; hatayı düzeltmeden servisi yeniden başlatırsanız site tamamen kapanabilir.

    Küçük bir performans notu: AllowOverride All, Apache'nin her istekte dizin ağacındaki tüm .htaccess dosyalarını okuması demektir. Yoğun sitelerde kuralları doğrudan sanal sunucu yapılandırmasına taşıyıp AllowOverride None bırakmak daha hızlıdır — ama o zaman WordPress kalıcı bağlantıları güncelleyemez, kuralı elle yönetmeniz gerekir.

    Nginx: try_files Kuralı Tanımlı Değilse#

    Nginx .htaccess dosyasını hiç okumaz. Bu cümle basit görünür ama bu yazının varlık sebebi odur: Nginx sunucusunda .htaccess dosyasını düzeltmek, dosyaya doğru kuralı yazmak, izinlerini değiştirmek — hepsi tamamen etkisizdir. Nginx yalnızca kendi sunucu bloğunu okur ve WordPress'in güzel adresleri için gereken kural oraya elle yazılmalıdır.

    Aradığınız satır tek bir tanedir:

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

    Bu satır Nginx'e şunu söyler: gelen adresi önce dosya olarak ara ($uri), bulamazsan klasör olarak ara ($uri/), onu da bulamazsan isteği sorgu dizesiyle birlikte index.php'ye devret. Üçüncü adım olmadığında Nginx doğrudan 404 döner — sitenizde tam olarak yaşadığınız şey budur.

    Yapılandırmanızı kontrol edin:

    grep -rn "try_files" /etc/nginx/sites-available/ /etc/nginx/conf.d/
    

    Sonuç boşsa ya da try_files $uri $uri/ =404; görüyorsanız neden bulunmuştur. Çalışan tam bir sunucu bloğu şöyledir:

    server {
        listen 443 ssl http2;
        server_name ornek.com www.ornek.com;
        root /var/www/ornek.com;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
    
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        }
    
        location = /favicon.ico { log_not_found off; access_log off; }
        location = /robots.txt  { log_not_found off; access_log off; allow all; }
    
        location ~* \.(js|css|png|jpg|jpeg|gif|webp|svg|ico|woff2)$ {
            expires max;
            log_not_found off;
        }
    
        location ~ /\.ht {
            deny all;
        }
    }
    

    Değişiklikten sonra sözdizimini sınayıp yeniden yükleyin:

    nginx -t
    systemctl reload nginx
    

    nginx -t çıktısı syntax is ok ve test is successful demiyorsa reload etmeyin; hatalı yapılandırmayla yeniden yükleme sunucudaki tüm siteleri düşürebilir.

    İki sık yapılan hataya dikkat edin. Birincisi, try_files satırını location ~ \.php$ bloğunun içine yazmak — orada işe yaramaz, kök location / bloğunda olmalıdır. İkincisi, ?$args kısmını unutmak: /index.php yazıp ?$args yazmazsanız sayfalama, arama ve önizleme bağlantıları sorgu parametrelerini kaybeder; sonuçta yazılar açılır ama ?s=arama ya da /sayfa/2/ çalışmaz. PHP-FPM tarafını doğru bağlamak için nginx php-fpm yapılandırma yazısına, sıfırdan kurulum için nginx kurulumu ubuntu yazısına bakabilirsiniz.

    WordPress alt dizindeyse#

    Site https://ornek.com/blog/ altındaysa try_files hedefi de o dizin olmalıdır:

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

    Apache tarafında karşılığı RewriteBase /blog/ ve RewriteRule . /blog/index.php [L] satırlarıdır. Alt dizin kurulumlarının taşınması ve adres yapısı için wordpress alt dizinden taşıma yazısı işinizi görür.

    Hızlı Teşhis Tablosu#

    BelirtiMuhtemel nedenKontrolÇözüm
    404 sayfası temanızın tasarımındaİstek WordPress'e ulaşıyorYazının durumu, slugİçerik/taksonomi tarafına bakın
    Çıplak Apache "Not Found".htaccess yok ya da okunmuyorls -la .htaccessDosyayı oluşturun, AllowOverride All
    Nginx gri 404 ekranıtry_files tanımsızgrep -rn try_filestry_files $uri $uri/ /index.php?$args;
    Ana sayfa dahil her şey 404Kök dizin (root) yanlışSunucu bloğu root satırıDoğru yolu yazın, reload
    Yazılar açılıyor, sayfalama 404?$args eksik ya da kural sıralamasıNginx bloğu?$args ekleyin
    Kaydet'e basınca kural yazılmıyor.htaccess yazılabilir değills -la, sahiplikchown + chmod 644

    Kural Doğruyken Devam Eden 404'ler#

    Yönlendirme sağlamsa (yani 404 sayfası temanızın tasarımıyla geliyorsa) neden başka yerdedir. Sık görülen dört durum şunlardır:

    1. Yazı yayımlanmamış. Taslak, beklemede ya da özel durumundaki bir yazı, oturum açmamış ziyaretçiye 404 döner. Yazı listesinde durumu kontrol edin.
    2. Slug çakışması. Bir sayfa ile bir kategori aynı adresi paylaşıyorsa biri erişilemez hâle gelir. Örneğin hizmetler adında hem bir sayfa hem bir kategori tabanı varsa çakışma yaşanır. Ayarlar → Kalıcı Bağlantılar ekranındaki kategori tabanını değiştirmek çözer.
    3. Özel yazı türü kayıtlı değil. Bir eklentiyi devre dışı bıraktıysanız, o eklentinin oluşturduğu ürün/portföy türü artık tanımlı değildir; içerik veritabanında durur ama adresi 404 döner. Eklentiyi geri açmak ya da yazıları standart türe taşımak gerekir.
    4. Önbellek. Sunucu ya da CDN önbelleği, sorunun yaşandığı andaki 404 yanıtını saklamış olabilir. Düzeltme sonrası tarayıcıyı değil, önbellek katmanını temizleyin ve gizli pencerede test edin.

    Bunlardan hiçbiri uymuyorsa, klasik eleme yöntemi işe yarar: tüm eklentileri geçici olarak kapatın, varsayılan temaya geçin ve bir yazıyı açın. Açılıyorsa suçlu eklenti ya da temadır; teker teker açarak bulursunuz. WordPress'te genel arıza teşhisinin sırasını wordpress hata çözümü yazısında topladım.

    Sıkça Sorulan Sorular#

    Kalıcı bağlantıları kaydettim ama hiçbir şey değişmedi#

    Bu, kuralın ya yazılamadığını ya da sunucu tarafından okunmadığını gösterir. Apache kullanıyorsanız .htaccess dosyasının var olduğunu ve içinde # BEGIN WordPress bloğunun bulunduğunu doğrulayın; dosya boşsa WordPress yazma izni bulamamıştır. Nginx kullanıyorsanız bu düğmenin hiçbir etkisi olmaz, çünkü Nginx .htaccess okumaz ve kural sunucu bloğunda tanımlanmalıdır. Önce curl -sI ile hangi sunucuda olduğunuzu kesinleştirin, sonra ilgili bölümü uygulayın.

    Nginx kullanıyorum, .htaccess dosyasını düzelttim ama sorun sürüyor#

    Nginx .htaccess dosyasını hiçbir koşulda okumaz, dolayısıyla o dosyada yaptığınız hiçbir değişiklik sonucu etkilemez. WordPress'in güzel adresleri için gereken kural, sitenizin sunucu bloğundaki location / içine try_files $uri $uri/ /index.php?$args; satırı olarak yazılmalıdır. Değişiklikten sonra nginx -t ile sözdizimini sınayın ve systemctl reload nginx ile yeniden yükleyin. Dosya yolunu bulamıyorsanız grep -rn "server_name ornek.com" /etc/nginx/ komutu doğru dosyayı gösterir.

    Ana sayfa dahil her sayfa 404 veriyorsa neden farklı mıdır#

    Evet, bu farklı bir arızadır ve genellikle sunucu bloğundaki root satırının yanlış dizini göstermesinden kaynaklanır. Yalnızca iç sayfalar 404 veriyorsa yönlendirme kuralı eksiktir; her şey 404 veriyorsa sunucu WordPress dosyalarını hiç bulamıyordur. root değerinin index.php dosyasının bulunduğu dizin olduğunu doğrulayın ve sunucu bloğunda server_name değerinin gerçekten sizin alan adınızla eşleştiğinden emin olun; eşleşmiyorsa istek varsayılan bloğa düşer.

    404 sayfası temamın tasarımıyla geliyorsa ne anlama gelir#

    İsteğin WordPress'e başarıyla ulaştığı, ancak WordPress'in o adrese karşılık gelen bir içerik bulamadığı anlamına gelir. Yönlendirme kuralları çalışıyordur, dolayısıyla .htaccess ya da Nginx yapılandırmasıyla uğraşmanıza gerek yoktur. Bu durumda yazının yayımlanmış olup olmadığını, adres kısmının (slug) değişip değişmediğini ve bir kategori ya da sayfa adıyla çakışma olup olmadığını kontrol edin. Özel yazı türlerinde, o türü kaydeden eklentinin devre dışı kalması da aynı sonucu üretir.

    Site taşıdıktan sonra yazılar 404 vermeye başladı#

    Bu son derece tipiktir ve neredeyse her zaman yönlendirme kuralının yeni sunucuya gelmemesinden kaynaklanır. FTP istemcilerinin çoğu nokta ile başlayan dosyaları varsayılan olarak göstermez ve aktarmaz; bu yüzden .htaccess eski sunucuda kalır. Apache'ye taşındıysanız kalıcı bağlantıları kaydederek dosyayı yeniden ürettirin. Apache'den Nginx'e geçtiyseniz kuralı yeni sunucu bloğuna elle yazmanız gerekir, çünkü eski dosya taşınsa bile Nginx onu okumaz.

    AllowOverride All ayarı güvenlik açığı yaratır mı#

    Doğrudan bir açık yaratmaz, ancak dizinlere yazma yetkisi olan tarafların sunucu davranışını değiştirebilmesi anlamına gelir. Tek sitelik kendi sunucunuzda ve dosya sahipliği doğru ayarlanmışsa bu makul bir yapılandırmadır. Asıl maliyeti güvenlik değil performanstır: Apache her istekte dizin ağacındaki tüm .htaccess dosyalarını okur. Yoğun trafikli sitelerde kuralları doğrudan sanal sunucu yapılandırmasına taşıyıp bu ayarı kapatmak daha verimlidir, ancak o zaman kalıcı bağlantı değişikliklerini elle yönetmeniz gerekir.

    Yazılar açılıyor ama sayfa 2 ve arama sonuçları 404 veriyor#

    Bu, yönlendirme kuralının sorgu dizesini aktarmamasından kaynaklanır. Nginx tarafında try_files satırının sonundaki hedefin /index.php?$args; olması gerekir; ?$args kısmı eksikse sayfalama, arama ve önizleme bağlantıları parametrelerini kaybeder. Apache tarafında ise standart WordPress bloğunun üstüne eklenmiş ve QSA bayrağı taşımayan bir eklenti kuralı aynı sonucu üretebilir. Kuralları standart hâline döndürüp test etmek en hızlı ayrım yöntemidir.

    Kapanış#

    Yalnızca iç sayfaların 404 vermesi, aslında dar ve iyi tanımlanmış bir arızadır: sunucu, var olmayan bir klasörü arıyor ve isteği index.php'ye devretmiyor. Teşhis üç soruya iner — 404 sayfası temanızın tasarımında mı geliyor, sunucunuz Apache mi Nginx mi, ilgili yönlendirme kuralı tanımlı ve okunuyor mu. Apache'de sıra .htaccess varlığı, mod_rewrite ve AllowOverride şeklindedir; Nginx'te tek satırlık try_files kuralıdır ve .htaccess ile uğraşmak orada tamamen zaman kaybıdır. Kural sağlamken devam eden 404'ler ise yayım durumu, slug çakışması ya da kayıtlı olmayan özel yazı türü gibi WordPress içi nedenlere işaret eder.

    Bu tür sunucu bloğu düzenlemelerini kendiniz yapmak istiyorsanız kök erişimi veren bir VDS sunucu size Nginx yapılandırmasına doğrudan müdahale imkânı verir; yapılandırmayı, güncellemeleri ve güvenlik ayarlarını devretmeyi tercih ederseniz sunucu yönetimi hizmeti bu işi üstlenir. Kalıcı bağlantı, .htaccess ve önbellek katmanları önceden doğru ayarlanmış bir ortamda çalışmak istiyorsanız WordPress hosting paketleri bu yapılandırmayla gelir. Taşıma sırasında .htaccess ve yönlendirme kurallarının unutulmasından kaynaklanan bu tür kesintileri hiç yaşamamak içinse site taşıma hizmetiyle aktarımı baştan sona bize bırakabilirsiniz.

    hata kodukalıcı bağlantıwordpress

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.