Apache: exit signal File size limit exceeded (25)

Vor einigen Tagen wurde ich zu einem Projekt zu Hilfe gerufen, an dem ich zuvor bereits einige Jahre lang als Systemadministrator und Softwareentwickler mitgearbeitet hatte.

Die Supportmitarbeiterin beschrieb mir die Symptome wie folgt: der Upload von Videos über das Online-Formular funktionierte nicht richtig. Die Datei wurde zwar hochgeladen, jedoch funktionierte die Fortschrittsanzeige nicht.

Eine Reihe von Test-Uploads bestätigte, daß die per AJAX abgerufene URL, die den Fortschritt des Uploads zurückliefern sollte, stattdessen einen Verbindungsabbruchsfehler (connection aborted) zurücklieferte.

Nachdem ich alle anderen möglichen Fehlerursachen ausgeschlossen hatte, entdeckte ich im Apache-ErrorLog eine große Anzahl dieser Fehlermeldungen
[notice] child pid XXXXX exit signal File size limit exceeded (25)

Ein weiterer Testupload ergab, daß dieser Fehler tatsächlich jedes Mal auftrat, wenn die Webseite versuchte, den Status des Uploads abzurufen. Aber wieso?

Eine Google-Suche nach der Fehlermeldung ergab fast nur Hinweise auf zu große Apache-Logdateien, doch tatsächlich wurden alle Logdateien des Webservers ordnungsgemäß rotiert und waren weit unter 2 GB groß.

Was also konnte dann die Ursache für den plötzlich auftauchenden Fehler sein?

Zum Glück erinnerte ich mich, schon früher einmal eine sehr große Datei namens „uploadprogress.txt“ in einem der Datenverzeichnisse des betroffenen Webprojekts gesehen zu haben. Und tatsächlich war diese Datei vorhanden und war nur wenige Bytes kleiner als die „magische“ Grenze von 2 GB. Ein Blick in den Code zeigte mir, daß bei jeder Anfrage nach dem Fortschritt des Uploads der aktuelle Status in diese Datei geschrieben wurde, die – da sie sich nicht in einem Verzeichnis befand, in dem Logdateien üblicherweise abgelegt werden – auch niemals automatisch rotiert wurde. Nachdem ich mich vergewissert hatte, daß der Inhalt dieser Datei nirgendwo sonst benötigt wird, habe ich sie gelöscht, und alles funktionierte wieder.

Was also war genau passiert?

Der betroffene Server war einer der wenigen, die noch mit einer 32bit-Version des Betriebssystems (CentOS) liefen. Unter 32bit Systemen können Applikationen, die nicht die „Large File“ APIs nutzen, maximal mit Dateigrößen bis 2GB (2^31 Bytes) umgehen. Versucht die Applikation, eine Dateioperation über dieses Limit hinaus durchzuführen, wird das Signal SIGXFSZ ausgelöst, und da PHP bzw. das Apache-Modul für PHP dieses nicht selbst behandelt, landet es im entsprechenden Apache-Kindprozess, der die Standardaktion für dieses Signal ausführt und sich beendet.

Fazit? Tritt so ein Fehler in den Apache-Logs auf und läuft PHP als Apache-Modul, dann sollten nicht nur die Apache-Logfiles überprüft werden, sondern auch alle von PHP-Scripts beschriebenen Dateien (nicht nur Logdateien, sondern auch z.B. dynamisch generierte Dokumente oder ZIP-Archive kommen hier in Frage.)