Bali, Indonesia
Insights

Situs WordPress Macet di Mode Maintenance Setelah Auto-Update? Cek File .maintenance

November 1, 2026
0:00
Situs WordPress tiba-tiba hanya menampilkan satu kalimat: Briefly unavailable for scheduled maintenance. Check back in a minute. Tidak ada yang sengaja menyalakan mode maintenance. Yang terjadi cuma auto-update core atau plugin berjalan di belakang layar. Solusi yang beredar di mana-mana adalah hapus file .maintenance, dan memang situs biasanya langsung kembali. Masalahnya, file itu cuma penanda. Menghapusnya tidak menjawab pertanyaan yang lebih penting: update tadi sebenarnya selesai atau berhenti di tengah jalan? Artikel ini membahas apa yang terjadi di dalam proses update WordPress, kenapa penanda itu bisa tertinggal, dan apa saja yang perlu dicek sebelum file itu dihapus.
File .maintenance ada di root instalasi WordPress, satu folder dengan wp-config.php. Isinya bukan konfigurasi, melainkan satu baris kode PHP yang menyimpan timestamp Unix (jumlah detik sejak 1 Januari 1970) saat mode maintenance dinyalakan. Bentuknya kira-kira seperti ini:
TEXT
<?php $upgrading = 1700000000; ?>
Angka di atas cuma contoh. Di server kamu nilainya adalah waktu saat updater mulai bekerja. Setiap kali ada request masuk, WordPress mengecek keberadaan file ini di tahap awal loading, sebelum plugin dan tema dimuat. Kalau file ada, WordPress meng-include file tersebut untuk membaca variabel $upgrading, lalu membandingkannya dengan waktu sekarang. Kalau dianggap masih dalam jendela maintenance, WordPress berhenti di situ dan mengirim halaman pesan tadi dengan status HTTP 503 (Service Unavailable). Karena berhenti sebelum plugin dimuat, plugin yang sedang diganti filenya tidak sempat dieksekusi dalam keadaan setengah jadi. Ada detail yang sering terlewat. Di versi WordPress modern, timestamp yang lebih tua dari sekitar 10 menit dianggap sudah kedaluwarsa, dan WordPress melanjutkan loading seperti biasa walaupun filenya masih ada. Jadi kalau pesan maintenance bertahan jauh lebih lama dari 10 menit, biasanya ada faktor lain. Contohnya, cache atau CDN menyimpan halaman 503 tersebut, auto-update dicoba ulang lewat cron dan menulis timestamp baru setiap kali gagal, atau ada plugin maintenance terpisah yang ikut aktif. Itu sebabnya hal pertama yang perlu dilihat adalah isi timestamp-nya, bukan langsung menghapus file.
Updater WordPress (kelas WP_Upgrader dan turunannya untuk core, plugin, dan tema) bekerja dalam urutan yang cukup bisa diprediksi. Kalau disederhanakan:
  1. Paket zip diunduh ke direktori temporary.
  2. Paket diekstrak ke folder staging wp-content/upgrade/.
  3. Mode maintenance dinyalakan dengan menulis .maintenance di root.
  4. File lama dihapus atau dipindah, lalu file baru disalin ke lokasi aslinya. Di versi yang lebih baru, plugin dan tema lama juga dibackup sementara ke wp-content/upgrade-temp-backup/ supaya bisa di-rollback.
  5. Folder staging dibersihkan.
  6. .maintenance dihapus dan mode maintenance selesai.
Untuk auto-update, ada satu lapisan lagi berupa lock di database. Sebelum mulai, WordPress menyimpan opsi seperti auto_updater.lock atau core_updater.lock di tabel wp_options agar dua proses update tidak jalan bersamaan. Lock ini punya masa berlaku, sehingga kalau prosesnya mati, lock akhirnya dianggap basi dan update bisa dicoba lagi. Yang penting dipahami, langkah 3 sampai 6 bukan transaksi atomik. Tidak ada mekanisme yang menjamin semua langkah selesai atau tidak satu pun dijalankan. Setiap langkah adalah operasi file biasa yang dijalankan oleh satu proses PHP. Kalau proses itu mati setelah langkah 3, .maintenance tertinggal. Kalau matinya di tengah langkah 4, sebagian file plugin sudah versi baru dan sebagian lagi masih versi lama, atau malah sudah terhapus. Pada bulk update, misalnya beberapa plugin diupdate sekaligus, biasanya hanya ada satu jendela maintenance untuk seluruh batch. Timestamp ditulis sekali di awal. Kalau batch-nya lama, situs bisa kembali terbuka saat plugin terakhir masih diproses, padahal updatenya belum selesai.
Auto-update tidak berjalan sebagai daemon tersendiri. Prosesnya dipicu oleh WP-Cron, yang secara default ikut dijalankan saat ada request ke situs, lalu dieksekusi sebagai request PHP biasa. Artinya auto-update terkena semua batasan yang berlaku untuk request web. Penyebab yang sering muncul:
  • Proses melewati max_execution_time PHP atau timeout di level PHP-FPM dan web server, terutama saat unduhan lambat atau update core yang filenya banyak.
  • Memori habis (Allowed memory size exhausted) atau proses dibunuh OOM killer di VPS yang RAM-nya pas-pasan.
  • Disk atau kuota inode penuh, sehingga ekstrak dan penyalinan file gagal di tengah jalan.
  • Owner atau permission file tidak cocok, sehingga sebagian file bisa ditimpa dan sebagian lain gagal. Ini sering terjadi setelah migrasi. Cara mengeceknya ada di Cara Cek Owner dan Permission File WordPress Setelah Pindah dari cPanel ke VPS.
  • Service PHP-FPM atau web server di-restart saat update sedang berjalan.
Dari sisi support, pola yang sering membingungkan pemilik situs adalah mereka tidak merasa melakukan apa-apa. Tidak ada yang klik tombol update, dan tidak ada yang menutup browser. Updatenya dipicu kunjungan pengunjung biasa lewat WP-Cron, lalu terputus oleh limit server. Karena itu, error log PHP di sekitar waktu yang tercatat di timestamp .maintenance biasanya jadi petunjuk paling jujur.
Sebelum menghapus apa pun, pastikan tidak ada proses update yang masih hidup. Kalau file dihapus saat proses masih menyalin file, pengunjung bisa masuk ke situs dalam kondisi setengah jadi. Langkah-langkah di bawah semuanya read-only dan aman dijalankan. Jalankan WP-CLI sebagai user pemilik file situs, bukan root, supaya tidak muncul masalah owner baru.
BASH
cd /path/ke/wordpress

# Lihat kapan mode maintenance dinyalakan
cat .maintenance
date -d @1700000000   # ganti angka dengan nilai $upgrading dari file

# Folder staging: kalau masih berisi, ekstrak atau penyalinan belum dibersihkan
ls -la wp-content/upgrade/

# Lock auto-update di database (error berarti opsi tidak ada)
wp option get auto_updater.lock
wp option get core_updater.lock

# Cari jejak proses yang terputus di error log (lokasi log tergantung setup)
grep -iE 'Maximum execution time|Allowed memory size' /path/ke/error_log | tail -n 20
Cara membacanya kira-kira begini. Kalau timestamp baru beberapa menit lalu, lock masih ada, dan folder wp-content/upgrade/ masih terisi, kemungkinan updatenya masih jalan. Tunggu dulu sambil pantau proses PHP milik user situs, misalnya lewat ps atau halaman status PHP-FPM kalau tersedia. Kalau timestamp sudah lama, tidak ada proses yang berjalan, dan error log menunjukkan timeout atau kehabisan memori di sekitar waktu tersebut, kamu bisa cukup yakin prosesnya mati di tengah jalan. Kalau ternyata pesan maintenance masih muncul padahal timestamp sudah lewat 10 menit, cek respons langsung dari origin dengan curl -I ke domain situs, sebaiknya sambil melewati CDN. Kalau origin sudah membalas 200 tetapi browser masih menerima 503, berarti yang perlu di-purge adalah cache, bukan file di server.
Di tahap ini kita perlu tahu apakah file yang sekarang ada di disk benar-benar sesuai dengan versi yang tercatat. WP-CLI bisa membandingkan file lokal dengan checksum resmi dari wordpress.org.
BASH
wp core version
wp core verify-checksums
wp plugin list --fields=name,status,version,update
wp plugin verify-checksums --all
Kalau situs sedang error, tambahkan --skip-plugins --skip-themes agar WP-CLI tidak ikut crash karena plugin yang rusak. Ada beberapa hal yang perlu diperhatikan dari hasilnya:
  • Checksum core gagal dengan banyak file yang tidak cocok atau hilang menandakan update core berhenti di tengah penyalinan.
  • Plugin yang tidak muncul di daftar, padahal sebelumnya aktif, biasanya berarti foldernya sudah terhapus tetapi versi baru belum sempat tersalin.
  • Plugin dengan checksum yang tidak cocok kemungkinan berisi campuran file versi lama dan baru.
  • Plugin premium yang tidak di-host di wordpress.org tidak bisa diverifikasi lewat checksum. Untuk plugin seperti ini, bandingkan versinya dengan paket asli dari vendor.
Perbaikannya adalah memasang ulang versi yang dituju, bukan menambal file satu per satu. Untuk plugin, wp plugin install nama-plugin --version=x.y.z --force akan menimpa folder plugin dengan paket utuh. Untuk core, wp core download --version=x.y.z --skip-content --force mengunduh ulang file core tanpa menyentuh wp-content. Perintah ini menimpa file, jadi pastikan sudah ada backup terbaru dan versi yang ditulis memang versi yang ingin dipasang. Kalau update core berhenti setelah file diganti tetapi sebelum upgrade database berjalan, wp core update-db akan menyelesaikan bagian tersebut. Setelah semuanya terverifikasi, barulah mode maintenance dimatikan, dengan wp maintenance-mode deactivate kalau versi WP-CLI kamu mendukung perintah itu, atau cukup rm .maintenance dari root instalasi. Folder wp-content/upgrade/ yang tertinggal juga boleh dikosongkan setelah kamu yakin tidak ada proses update yang aktif. Kalau situs malah blank putih atau error 500 setelah dibuka, langkah melacak plugin penyebabnya ada di Cara Cek Plugin Penyebab White Screen WordPress Lewat WP-CLI Tanpa Buka Admin.
Akar masalahnya hampir selalu sama: proses update yang cukup berat dijalankan dalam batasan request web biasa. Beberapa hal yang biasanya membantu adalah memberi ruang memori dan timeout yang wajar untuk PHP, memastikan disk dan inode tidak mepet, menjalankan WP-Cron lewat cron sistem alih-alih menunggu kunjungan pengunjung, dan menjalankan update besar lewat WP-CLI. Proses CLI tidak terikat timeout web server, dan error-nya langsung terlihat di terminal. Intinya, .maintenance adalah gejala, bukan penyakitnya. Lihat dulu timestamp di dalamnya, pastikan tidak ada lock atau proses update yang masih hidup, verifikasi checksum core dan plugin, pasang ulang yang tidak utuh, lalu hapus file itu paling akhir. Urutan ini hanya butuh beberapa menit tambahan, tetapi bisa mencegah situs dibuka dalam kondisi setengah terupdate yang jauh lebih sulit dilacak nanti.