Ratgeber

WordPress: geplanter Beitrag wird nicht veröffentlicht - Ursachen und Lösung

Der Beitrag sollte um 9 Uhr online gehen, mittags steht er immer noch auf „Überfällig“. Hier lesen Sie, wie WordPress geplante Beiträge veröffentlicht, was das meistens verhindert und wie Sie es dauerhaft beheben.

Stand:

Kurz gesagt: WordPress veröffentlicht geplante Beiträge nicht mit einer Uhr, die ständig läuft. Zuständig ist WP-Cron, und WP-Cron prüft nur dann auf fällige Aufgaben, wenn jemand eine Seite aufruft. Kommt niemand vorbei, hält ein Cache die Aufrufe von WordPress fern, kann sich die Website nicht selbst erreichen (Loopback) oder ist WP-Cron ohne Ersatz abgeschaltet, bleibt der Beitrag auf „Überfällig“ stehen. Die zuverlässige Lösung ist ein echter Cronjob auf dem Server, der alle paar Minuten wp-cron.php aufruft, zusammen mit DISABLE_WP_CRON. Prüfen Sie außerdem die Zeitzone unter Einstellungen > Allgemein.

Was „Überfällig“ in der Beitragsliste bedeutet

Wenn Sie einen Beitrag planen, bekommt er in WordPress den Status future. In der Beitragsliste zeigt WordPress dann „Geplant“, solange der Termin in der Zukunft liegt. Ist der Termin vorbei und der Beitrag hat immer noch den Status future, erscheint in Rot „Überfällig“. Im englischen WordPress heißt dieser Hinweis „Missed schedule“, die deutsche Übersetzung „Überfällig“ finden Sie auf translate.wordpress.org (externer Link). Die Logik dahinter steht im Quelltext der Beitragsliste (WP_Posts_List_Table::column_date (externer Link)).

„Überfällig“ heißt also nicht, dass mit dem Beitrag etwas kaputt ist. Die Aufgabe, die ihn veröffentlichen sollte, ist nur noch nicht gelaufen.

Wie WordPress einen geplanten Beitrag veröffentlicht

Beim Planen legt WordPress ein einmaliges Ereignis mit dem Hook publish_future_post und der Beitrags-ID an, terminiert auf das Beitragsdatum in GMT (_future_post_hook (externer Link)). Läuft dieses Ereignis, prüft WordPress, ob der Beitrag noch den Status future hat und ob der Zeitpunkt erreicht ist, und veröffentlicht ihn dann (check_and_publish_future_post (externer Link)).

Ausgeführt wird das Ereignis von WP-Cron. Das Plugin-Handbuch von WordPress erklärt den Unterschied zu einem echten Cron: „WP-Cron works by checking, on every page load, a list of scheduled tasks to see what needs to be run.“ Und: „WP-Cron does not run constantly as the system cron does; it is only triggered on page load.“ Sinngemäß: WP-Cron prüft bei jedem Seitenaufruf, welche Aufgaben fällig sind, und läuft nicht dauerhaft wie ein Cron des Betriebssystems. Das Handbuch nennt ein Beispiel: Ist eine Aufgabe für 14 Uhr geplant und ruft bis 17 Uhr niemand eine Seite auf, läuft sie erst dann (Plugin-Handbuch: Cron (externer Link)).

Bei einem Seitenaufruf startet WordPress den Cron-Lauf mit einer kurzen Anfrage an die eigene Datei wp-cron.php, ohne das Laden der Seite aufzuhalten (spawn_cron (externer Link)). Diese Anfrage der Website an sich selbst heißt Loopback-Anfrage. Der Website-Zustand beschreibt es genauso: Loopback-Anfragen werden verwendet, um geplante Ereignisse auszuführen (Site Health screen (externer Link)).

Damit ein geplanter Beitrag pünktlich erscheint, müssen also drei Dinge funktionieren:

  1. Um den geplanten Zeitpunkt herum erreicht ein Seitenaufruf WordPress.
  2. WordPress kann die Loopback-Anfrage an wp-cron.php senden.
  3. Der Cron-Lauf geht ohne Fehler durch.

Die häufigsten Ursachen

UrsacheWas passiertWo Sie nachsehen
Wenig BesucherNiemand ruft eine Seite auf, also startet WP-Cron nicht (Plugin-Handbuch (externer Link)).Erscheint der Beitrag, sobald Sie selbst die Website öffnen?
DISABLE_WP_CRON ohne echten CronjobWP-Cron startet nicht mehr bei Seitenaufrufen, und nichts anderes ruft es auf (wp-config.php (externer Link)).wp-config.php; wp cron test meldet einen Fehler (WP-CLI (externer Link)).
Seiten-Cache oder CDNWP-Cron wird beim Seitenaufruf in WordPress ausgelöst. Beantwortet ein Cache die Anfrage, ohne WordPress zu starten, löst dieser Besuch nichts aus.Cache- und CDN-Einstellungen beim Hoster oder im Plugin.
Loopback-Anfrage blockiertDie Anfrage an wp-cron.php schlägt fehl, fällige Ereignisse laufen nicht (WP_Site_Health::can_perform_loopback (externer Link)).Werkzeuge > Website-Zustand > Zustand.
Firewall, Sicherheits-Plugin oder PasswortschutzEine Regel sperrt Anfragen an wp-cron.php oder vom eigenen Server. Die Cron-Anfrage schickt keine Zugangsdaten mit (spawn_cron (externer Link)).Firewall-Protokoll, Sicherheits-Plugin, Passwortschutz des Servers.
Falsche ZeitzoneWordPress rechnet das Beitragsdatum von der Zeitzone der Website in GMT um (_future_post_hook (externer Link)). Eine falsche Einstellung verschiebt die echte Veröffentlichungszeit.Einstellungen > Allgemein > Zeitzone.
Cronjob auf dem Server falsch eingerichtetDie Cron-Zeile nutzt eine falsche Adresse, einen falschen Pfad oder läuft nie.crontab -l, Hosting-Verwaltung, Server-Protokoll.
PHP-FehlerEin schwerer Fehler im Cron-Lauf kann ihn abbrechen, bevor der Beitrag veröffentlicht ist.wp-content/debug.log (Debugging in WordPress (externer Link)).

Diagnose Schritt für Schritt

Gehen Sie die Schritte in dieser Reihenfolge durch. Meist ist die Ursache spätestens nach Schritt 3 klar.

Schritt 1: Zeitzone prüfen

Öffnen Sie Einstellungen > Allgemein > Zeitzone. Die WordPress-Dokumentation empfiehlt, eine Stadt in Ihrer Zeitzone zu wählen, für Deutschland also zum Beispiel „Berlin“. Nach dem Speichern zeigt WordPress die UTC-Zeit und die Ortszeit an, damit Sie die Einstellung kontrollieren können (Settings General screen (externer Link)). Eine Stadt berücksichtigt die Sommerzeit, ein fester UTC-Versatz wie „UTC+1“ nicht.

Öffnen Sie dann den geplanten Beitrag und vergleichen Sie seinen Termin mit der angezeigten Ortszeit.

Schritt 2: Website-Zustand prüfen

Öffnen Sie Werkzeuge > Website-Zustand (Site Health screen (externer Link)). Achten Sie im Tab „Zustand“ auf diese Meldungen:

  • „Deine Website konnte eine Loopback-Anfrage nicht abschließen“: WordPress erreicht sich nicht selbst, geplante Ereignisse können nicht starten.
  • „Ein geplantes Ereignis ist fehlgeschlagen“ oder „Ein geplantes Ereignis ist überfällig“: WP-Cron führt Ereignisse nicht pünktlich aus (WP_Site_Health::get_test_scheduled_events (externer Link)).

So lauten die Meldungen in der offiziellen deutschen Übersetzung (dort in der Du-Form). Im Tab „Bericht“ finden Sie unter anderem die eingestellte Zeitzone und die WordPress-Konstanten.

Eine Einschränkung: Der Loopback-Test im Website-Zustand reicht HTTP-Zugangsdaten weiter, wenn der Browser welche gesendet hat (can_perform_loopback (externer Link)). Die normale Cron-Anfrage sendet keine (spawn_cron (externer Link)). Auf einer Testseite hinter einem Server-Passwort kann der Test also grün sein, während WP-Cron trotzdem scheitert.

Schritt 3: WP-Cron mit WP-CLI prüfen

Wenn Sie SSH-Zugang und WP-CLI (externer Link) haben, führen Sie diese Befehle im WordPress-Ordner aus.

Testen, ob WP-Cron starten kann:

wp cron test

Funktioniert alles, lautet die Ausgabe Success: WP-Cron spawning is working as expected. Der Befehl meldet einen Fehler, wenn DISABLE_WP_CRON gesetzt ist, und warnt, wenn die Anfrage nicht mit Status 200 antwortet (wp cron test (externer Link)).

Geplante Ereignisse auflisten und nach publish_future_post suchen:

wp cron event list --fields=hook,next_run_gmt,next_run_relative,args

Standardmäßig zeigt der Befehl hook, next_run_gmt, next_run_relative und recurrence, args ist ein optionales Feld (wp cron event list (externer Link)). Steht das Ereignis für Ihren Beitrag mit einem Zeitpunkt in der Vergangenheit in der Liste, ist WP-Cron seitdem nicht gelaufen.

Alle fälligen Ereignisse von Hand ausführen:

wp cron event run --due-now

Damit laufen alle Hooks, die jetzt fällig sind (wp cron event run (externer Link)). Ist der Beitrag danach veröffentlicht, funktioniert das Veröffentlichen an sich, und es fehlt nur der Auslöser. Zeigt der Befehl einen Fehler, schauen Sie als Nächstes ins PHP-Fehlerprotokoll.

Schritt 4: PHP-Fehler suchen

Schalten Sie das Protokoll in der wp-config.php ein, oberhalb der Zeile „That's all, stop editing!“ (Debugging in WordPress (externer Link)):

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

Das Protokoll landet in der Datei debug.log im Content-Ordner, meist wp-content/debug.log. Führen Sie wp cron event run --due-now noch einmal aus und lesen Sie das Protokoll. Schalten Sie den Debug-Modus danach wieder aus: Der Website-Zustand warnt, wenn die Protokolldatei öffentlich erreichbar sein könnte (Site Health screen (externer Link)).

Lösung 1: echten Cronjob auf dem Server einrichten (empfohlen)

So hängt das Veröffentlichen nicht mehr von Besuchern ab. Das Plugin-Handbuch beschreibt das in zwei Teilen (Hooking WP-Cron into the system task scheduler (externer Link)).

Teil 1: WP-Cron bei Seitenaufrufen abschalten. Ergänzen Sie in der wp-config.php diese Zeile:

define( 'DISABLE_WP_CRON', true );

Sie gehört oberhalb der Zeile „That's all, stop editing!“ und vor jedes require_once (wp-config.php (externer Link)).

Teil 2: wp-cron.php über den Cron des Servers aufrufen. Öffnen Sie die Crontab mit crontab -e und tragen Sie eine Zeile ein. Das Handbuch nutzt */15 * * * * für alle 15 Minuten und wget --delete-after für den Aufruf; ohne --delete-after würde wget die Antwort als Datei speichern:

*/15 * * * * wget --delete-after https://www.example.de/wp-cron.php

Ersetzen Sie www.example.de durch Ihre Domain. Den Abstand überlässt das Handbuch Ihnen. Sollen Beiträge minutengenau erscheinen, ist ein kürzerer Abstand sinnvoll. Bei alle 5 Minuten geht ein Beitrag höchstens etwa 5 Minuten zu spät online:

*/5 * * * * wget -q --delete-after https://www.example.de/wp-cron.php

Ist WP-CLI auf dem Server installiert, kann es die fälligen Ereignisse auch direkt ausführen, ohne Umweg über HTTP (wp cron event run (externer Link)):

*/5 * * * * /usr/local/bin/wp --path=/var/www/example cron event run --due-now --quiet

Setzen Sie Ihren echten WordPress-Pfad ein. Viele Hoster bieten in ihrer Verwaltung ein Formular für Cronjobs statt crontab -e, eingetragen wird derselbe Befehl.

Erledigen Sie immer beide Teile. DISABLE_WP_CRON allein schaltet die Planung komplett ab und ist selbst eine der Ursachen oben.

Prüfen Sie danach:

wp cron event list --fields=hook,next_run_relative

Kein Ereignis sollte länger als Ihr Cron-Abstand in der Vergangenheit stehen bleiben.

Lösung 2: Loopback-Anfrage reparieren

Wenn WP-Cron weiter bei Seitenaufrufen laufen soll, muss die Website sich selbst erreichen:

  • Firewall und Sicherheits-Plugins: Anfragen an /wp-cron.php zulassen, auch vom eigenen Server.
  • Testseiten mit Passwortschutz: Die Cron-Anfrage sendet keine Zugangsdaten (spawn_cron (externer Link)). Nehmen Sie wp-cron.php vom Schutz aus oder nutzen Sie einen Cronjob mit WP-CLI wie in Lösung 1.
  • PHP-Sitzungen: Der Website-Zustand warnt, dass eine mit session_start() erzeugte Sitzung REST-API- und Loopback-Anfragen beeinträchtigt (Site Health screen (externer Link)). Suchen Sie das Plugin, das die Sitzung startet.
  • Cache: Bleibt WP-Cron an Seitenaufrufe gebunden, müssen genug Aufrufe wirklich bei WordPress ankommen. Ein Cronjob auf dem Server (Lösung 1) nimmt Ihnen diese Abhängigkeit ab.

Öffnen Sie danach erneut Werkzeuge > Website-Zustand. Dort sollte „Deine Website kann Loopback-Anfragen durchführen“ stehen.

WordPress kennt außerdem ALTERNATE_WP_CRON. Laut Dokumentation wird es meist genutzt, wenn geplante Beiträge nicht wie vorgesehen erscheinen: Der Browser der Besucher wird umgeleitet, während Cron in der abgebrochenen Verbindung weiterläuft. Die Dokumentation weist selbst auf Risiken hin (wp-config.php (externer Link)). Nutzen Sie es nur als Notlösung, wenn Sie keinen Cronjob einrichten können.

Lösung 3: Zeitzone korrigieren

Wählen Sie unter Einstellungen > Allgemein > Zeitzone eine Stadt und speichern Sie (Settings General screen (externer Link)). Prüfen Sie anschließend die Termine der Beiträge, die Sie vor der Änderung geplant haben. Steht ein Beitrag nur wegen der falschen Zeitzone auf „Überfällig“, veröffentlichen Sie ihn von Hand oder geben ihm einen neuen Termin.

Checkliste zum Kopieren

[ ] Einstellungen > Allgemein > Zeitzone: Stadt gewählt, Ortszeit stimmt
[ ] Werkzeuge > Website-Zustand: kein Loopback-Fehler, kein überfälliges oder fehlgeschlagenes Ereignis
[ ] wp cron test: Success (nur wenn WP-Cron weiter bei Seitenaufrufen läuft; mit DISABLE_WP_CRON meldet der Befehl absichtlich einen Fehler)
[ ] wp cron event list: kein publish_future_post-Ereignis in der Vergangenheit
[ ] wp cron event run --due-now: Beitrag erscheint, kein Fehler
[ ] wp-config.php: DISABLE_WP_CRON nur auf true, wenn ein Cronjob läuft
[ ] crontab -l: Zeile ruft alle 5-15 Minuten wp-cron.php auf (oder wp cron event run --due-now)
[ ] Firewall, Sicherheits-Plugin, Passwortschutz: wp-cron.php erlaubt
[ ] wp-content/debug.log: keine schweren Fehler im Cron-Lauf

Planen mit Blog Automation

In Blog Automation planen Sie freigegebene Beiträge im Redaktionskalender. Er zeigt geplante, veröffentlichte und fehlgeschlagene Beiträge. Für jede verbundene Website stellen Sie eine eigene Zeitzone ein, prüfen Sie also, ob sie zu Ihrer WordPress-Zeitzone passt. Schlägt eine Veröffentlichung fehl, erscheint der Beitrag im Dashboard unter „Braucht Aufmerksamkeit“ mit der Fehlermeldung von WordPress, und eine E-Mail-Benachrichtigung informiert Sie. Wie die Verbindung mit oder ohne Plugin funktioniert, lesen Sie auf der Seite Blog Automation für WordPress. Den ganzen Ablauf von der Idee bis zum veröffentlichten Beitrag beschreibt unser Ratgeber Blog automatisieren mit WordPress.

Häufige Fragen

Warum erscheint mein geplanter Beitrag erst, wenn ich die Website öffne?

Weil WP-Cron durch Seitenaufrufe ausgelöst wird (Plugin-Handbuch: Cron (externer Link)). Ihr eigener Besuch startet die überfällige Aufgabe. Auf Websites mit wenig Besuchern hilft ein Cronjob auf dem Server wie in Lösung 1.

Wie veröffentliche ich einen Beitrag, der schon auf „Überfällig“ steht?

Öffnen Sie den Beitrag und klicken Sie auf „Veröffentlichen“, oder führen Sie mit WP-CLI wp cron event run --due-now aus (wp cron event run (externer Link)). Damit ist der Beitrag online (der Befehl führt alle fälligen Ereignisse aus), die Ursache aber nicht behoben. Gehen Sie danach die Diagnose durch.

Kann ich DISABLE_WP_CRON gefahrlos auf true setzen?

Nur zusammen mit einem Cronjob auf dem Server. Die Konstante schaltet WP-Cron bei Seitenaufrufen ab (wp-config.php (externer Link)). Ohne Ersatz laufen geplante Beiträge, Update-Prüfungen und andere geplante Aufgaben nicht mehr von selbst.

Betrifft das Problem nur Beiträge?

Nein, dasselbe System erledigt auch andere Aufgaben. Laut Website-Zustand sorgen geplante Ereignisse unter anderem dafür, dass regelmäßig nach Updates für Plugins, Themes und WordPress gesucht wird (WP_Site_Health::get_test_scheduled_events (externer Link)). Verpassen Beiträge ihren Termin, sind diese Aufgaben vermutlich ebenfalls zu spät dran.

Wie oft sollte der Cronjob laufen?

Das WordPress-Handbuch schreibt keinen Abstand vor (Hooking WP-Cron into the system task scheduler (externer Link)). Richten Sie sich danach, wie genau Ihre Termine sein müssen: Bei alle 5 Minuten erscheint ein Beitrag höchstens etwa 5 Minuten nach seinem Termin, bei alle 15 Minuten höchstens etwa 15 Minuten danach.

Bereit für den ersten Artikel?

Testen Sie Blog Automation mit Beispieldaten

Die Demo öffnet sofort, ganz ohne Anmeldung. Sie sehen Dashboard, Editor, Kalender und Freigabe so, wie Ihr Team später damit arbeitet.

Demo testen - ohne AnmeldungKostenlos starten

Die Demo zeigt Beispieltexte. Der Free-Plan enthält 200 Tokens im Monat.

Demo testen