Linux Festplatte voll: Ursache finden und Platz freigeben (2026)

Linux Festplatte voll: Ursache finden und Platz freigeben (2026)

Wenn die Linux Festplatte voll ist, merkst du es selten an einer freundlichen Warnung. Du merkst es daran, dass eine Datenbank nicht mehr startet, ein Deployment mit „No space left on device“ abbricht, SSH-Logins seltsam hängen oder eine Webseite plötzlich weiße Seiten ausliefert. Die gute Nachricht: Die Ursache lässt sich fast immer in wenigen Minuten finden, wenn du in der richtigen Reihenfolge suchst. Die schlechte: Es gibt mindestens vier Fälle, in denen die üblichen Befehle dir etwas anderes zeigen als die Wirklichkeit.

Wir kennen das Problem nicht aus Büchern. Ende September ist die Platte unseres eigenen Servers auf 100 Prozent gelaufen, mit null Byte frei. Für diesen Artikel haben wir deshalb nicht nur unseren Produktivserver vermessen, sondern auf ihm kleine Wegwerf-Dateisysteme angelegt und gezielt vollgeschrieben. So konnten wir jede Falle einzeln nachstellen: gelöschte Dateien, die weiter Platz belegen, ein Dateisystem, das „voll“ meldet, obwohl 55 MB frei sind, Daten, die unter einem Mountpoint verschwinden, und eine Konfigdatei, die beim Speichern auf null Byte schrumpft.

Ein Serverraum, in dem aus einem Rack leuchtende Flüssigkeit überläuft und sich über den Boden verteilt

Wenn dir Befehle wie df, du oder find noch fremd sind, schau zuerst in unsere Linux Befehle Liste. Dort steht die Grundausstattung. Hier geht es um den Ernstfall: Die Platte ist voll, und du willst wissen, warum, ohne dabei etwas Wichtiges zu löschen.

Linux Festplatte voll: die Kurzfassung in sieben Schritten

Wer gerade unter Druck steht, braucht keine Theorie, sondern eine Reihenfolge. Diese hier hat sich bei uns bewährt:

  1. Welches Dateisystem ist voll? df -h zeigt es. Nicht raten, denn /, /var und /home können getrennte Partitionen sein.
  2. Sind es Bytes oder Inodes? df -i. Steht dort 100 Prozent, hilft das Löschen großer Dateien gar nichts.
  3. Wer frisst den Platz? du -xh --max-depth=1 /pfad | sort -rh | head oder bequemer ncdu -x /pfad.
  4. Gibt es gelöschte, aber noch offene Dateien? lsof +L1. Das ist die häufigste Erklärung, wenn df und du sich widersprechen.
  5. Die üblichen Verdächtigen prüfen: journalctl --disk-usage, docker system df, /var/log, den Paket-Cache, alte Kernel, Datenbank-Binlogs, Backups im falschen Ordner.
  6. Gezielt aufräumen, mit Befehlen, die nur das löschen, was sie sollen.
  7. Dafür sorgen, dass es nicht wieder passiert: Grenzen für Logs setzen und eine Warnung, die dich weckt, bevor die Platte voll ist.

Jeder Schritt hat seine eigenen Fallstricke. Die gehen wir jetzt der Reihe nach durch, und zwar mit dem, was wir tatsächlich gemessen haben.

Was „No space left on device“ wirklich bedeutet

Die Fehlermeldung No space left on device (Fehlercode ENOSPC) klingt eindeutig, ist es aber nicht. Der Kernel gibt sie in mehreren Situationen zurück:

  • Es sind keine freien Datenblöcke mehr da. Das ist der klassische Fall.
  • Es sind keine freien Inodes mehr da. Jede Datei braucht genau einen Inode, egal wie klein sie ist. Sind die alle, kannst du keine neue Datei mehr anlegen, auch wenn noch Gigabytes frei sind.
  • Du bist ein normaler Benutzer, und die reservierten Blöcke für root sind das Einzige, was noch frei ist.
  • Ein Kontingent (Quota) ist erschöpft, oder bei Containern das Limit des Overlay-Dateisystems.

Die Meldung ist bei allen vier dieselbe. Deshalb bringt es nichts, beim ersten ENOSPC sofort die größte Datei zu suchen. Erst muss klar sein, welche Ressource fehlt und auf welchem Dateisystem.

Schritt 1: Mit df herausfinden, welches Dateisystem voll ist

df -h

df (disk free) zeigt pro eingehängtem Dateisystem Größe, Belegung, freien Platz und den Mountpoint. Auf unserem Server sah das beim Schreiben dieses Artikels so aus:

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       451G  400G   33G  93% /

Zwei Dinge fallen auf, die viele übersehen. Erstens: 451 minus 400 ergibt 51, nicht 33. Die fehlenden rund 18 GB sind keine Rechenfehler, sondern die reservierten Blöcke von ext4 (dazu gleich mehr). Zweitens: Wenn du wissen willst, auf welchem Dateisystem ein bestimmter Pfad liegt, frag df direkt nach dem Pfad:

df -h /var/lib/mysql
findmnt -T /var/lib/mysql

Das klingt banal, verhindert aber den häufigsten Fehler beim Aufräumen: Du löschst fleißig in /home, während eigentlich /var auf einer eigenen Partition voll ist. Der Platz, den du freiräumst, landet dann auf dem falschen Konto.

Mit df -hT bekommst du zusätzlich den Dateisystemtyp. Das ist wichtig, weil sich ext4, XFS und Btrfs beim Thema „voll“ unterschiedlich verhalten. Btrfs zum Beispiel zeigt bei df oft ungenaue Werte, weil Metadaten und Snapshots separat verwaltet werden. Dort ist btrfs filesystem usage / der verlässlichere Befehl.

Schritt 2: Inodes prüfen mit df -i

df -i

Dieser Befehl zeigt dieselben Dateisysteme, aber statt Bytes die Zahl der Inodes. Auf unserem Server lag die Belegung bei harmlosen 14 Prozent (gut 4 Millionen von 29 Millionen). Spannend wird es, wenn dort 100 Prozent steht.

Unser Test: voll mit 55 MB Platz

Wir haben ein kleines ext4-Dateisystem mit 64 MB, aber absichtlich nur 2.000 Inodes angelegt und dann leere Dateien geschrieben, bis nichts mehr ging. Nach 1.988 leeren Dateien kam:

s/f1988: No space left on device

Und jetzt der entscheidende Moment, der in jedem Notfall Verwirrung stiftet:

$ df -h imnt
/dev/loop3       60M   64K   55M   1% /tmp/gmdisk/imnt
$ df -i imnt
/dev/loop3       2000  2000     0  100% /tmp/gmdisk/imnt

df -h meldet 1 Prozent belegt und 55 MB frei. Trotzdem kann keine einzige neue Datei mehr entstehen. Wer nur auf df -h schaut, sucht an dieser Stelle stundenlang nach einer großen Datei, die es nicht gibt.

Eine riesige Wand aus winzigen Fächern, alle gefüllt, neben einem großen, fast leeren Tank

In der Praxis entstehen volle Inodes fast immer durch Millionen winziger Dateien: PHP-Sessions, die nie aufgeräumt werden, Cache-Ordner von Frameworks, Mail-Queues, Thumbnails oder ein Skript, das in einer Schleife Temp-Dateien anlegt. Finden kannst du den Verursacher, indem du nicht nach Größe, sondern nach Anzahl zählst:

# Dateien pro Ordner zählen, eine Ebene unter /var
sudo find /var -xdev -type f | cut -d/ -f3 | sort | uniq -c | sort -rn | head

# Neuere coreutils können das direkt
sudo du --inodes -x --max-depth=2 /var | sort -rn | head

Löschen solltest du dann nicht mit rm -rf ordner/*, weil die Shell bei Millionen Dateien mit „Argument list too long“ aussteigt. Besser ist find ordner -type f -mmin +120 -delete, das löscht nur Dateien, die älter als zwei Stunden sind, und läuft ohne Argumentliste.

Wichtig für die Zukunft: Bei ext4 wird die Zahl der Inodes beim Anlegen des Dateisystems festgelegt. Mehr bekommst du später nur durch Neuformatieren. XFS und Btrfs vergeben Inodes dynamisch, dort ist das Problem deutlich seltener.

Schritt 3: Mit du und ncdu den Platzfresser finden

Wenn df zeigt, dass es wirklich die Bytes sind, kommt du (disk usage). Der wichtigste Schalter dabei ist -x: Er sorgt dafür, dass du auf demselben Dateisystem bleibt und nicht in andere Mounts wie /proc, Netzlaufwerke oder eine zweite Platte abtaucht.

sudo du -xh --max-depth=1 / 2>/dev/null | sort -rh | head -10

Auf unserem Server dauerte dieser eine Befehl über die ganze 400-GB-Platte 37,7 Sekunden, fast ausschließlich Systemzeit für das Durchlaufen der Verzeichnisse. Ergebnis, gekürzt:

400G	/
306G	/root
34G	/var
25G	/usr
17G	/opt
9.7G	/tmp
5.0G	/home

Von hier aus hangelst du dich weiter: du -xh --max-depth=1 /root | sort -rh | head, dann eine Ebene tiefer, bis du beim Verursacher bist. Das geht, ist aber mühsam, weil jeder Aufruf wieder von vorn zählt.

Zwei leuchtende Kugeln über gläsernen Ebenen, eine rot, eine blau, vor dunklem Hintergrund

ncdu: einmal zählen, dann bequem durchklicken

Genau dafür gibt es ncdu. Es zählt einmal und zeigt dir dann eine sortierte, navigierbare Liste im Terminal. Mit den Pfeiltasten gehst du in Ordner hinein, mit d löschst du (nach Rückfrage), mit q beendest du.

sudo apt install ncdu       # Debian/Ubuntu
sudo dnf install ncdu       # Fedora/RHEL
sudo ncdu -x /

Ein praktisches Problem: Auf unserem Server war ncdu gar nicht installiert. Bei einer wirklich vollen Platte kann auch die Installation scheitern, weil apt Platz für Paketlisten und das Paket selbst braucht. Dann bleibt du, oder du räumst zuerst zwei, drei offensichtliche Dinge frei (Paket-Cache, Journal) und installierst danach.

Ein Tipp für große Server: ncdu kann seinen Scan in eine Datei exportieren (ncdu -x -o /tmp/scan.ncdu /) und später ohne erneutes Zählen wieder einlesen (ncdu -f /tmp/scan.ncdu). Die Exportdatei sollte dabei natürlich nicht auf der vollen Partition liegen.

Wer es moderner mag, findet in gdu eine schnellere Alternative mit paralleler Suche, und duf zeigt eine hübschere Version von df. Nötig sind beide nicht.

Große Dateien direkt suchen

Manchmal ist nicht ein Ordner das Problem, sondern eine einzelne riesige Datei: ein Core-Dump, ein vergessenes Backup, ein ISO, ein Datenbank-Export. Die findest du direkt:

sudo find / -xdev -type f -size +500M -printf '%s\t%p\n' 2>/dev/null | sort -rn | head

Über unser /var lief diese Suche in 2,8 Sekunden, also deutlich schneller als ein komplettes du, weil find nur Metadaten prüft und nichts aufsummieren muss.

Falle: ls und du zeigen unterschiedliche Größen

Wir haben eine Datei mit truncate -s 1G angelegt. Das ergibt eine sogenannte sparse file: Sie hat eine logische Größe, belegt aber nur die Blöcke, in die wirklich geschrieben wurde.

$ ls -lh sparse.img
-rw-r--r-- 1 root root 1.0G  sparse.img
$ du -h sparse.img
0	sparse.img
$ du -h --apparent-size sparse.img
1.0G	sparse.img

ls zeigt 1 GB, du zeigt 0. Für die Frage „Wo ist mein Platz hin?“ ist immer du die richtige Antwort, weil es echte Blöcke zählt. Virtuelle Festplatten von VMs, Docker-Images im Loop-Modus und manche Datenbankdateien sind oft sparse. Wer beim Aufräumen nach ls -l sortiert, löscht dann die falsche Datei.

Schritt 4: Gelöschte Dateien, die weiter Platz belegen

Das ist die Falle, die am meisten Zeit kostet, und sie ist in der Praxis erstaunlich häufig. Das Symptom: df sagt, die Platte ist voll. du findet aber viel weniger Daten. Irgendwo fehlen Gigabytes, und kein Ordner erklärt sie.

Unser Test

Wir haben auf einem 200-MB-Testdateisystem eine 100-MB-Datei angelegt und einen Prozess gestartet, der sie offen hält. Dann haben wir die Datei gelöscht:

$ df -h mnt      # vor rm
/dev/loop3      172M  101M   58M  64% /tmp/gmdisk/mnt
$ rm mnt/big.log
$ df -h mnt      # nach rm
/dev/loop3      172M  101M   58M  64% /tmp/gmdisk/mnt
$ du -sh mnt
20K	mnt

Die Datei ist weg, du findet nur noch 20 KB, aber df meldet weiter 101 MB belegt. Der Grund: Unter Linux entfernt rm nur den Verzeichniseintrag. Die Daten selbst werden erst freigegeben, wenn kein Prozess die Datei mehr geöffnet hat. Solange irgendwer noch einen Dateideskriptor darauf hält, bleibt der Platz belegt, unsichtbar für du und ls.

Eine geisterhafte, halb durchsichtige Datei, die über eine leuchtende Kette noch an einem laufenden Zahnrad hängt

Der typische Auslöser im echten Leben: Jemand sieht eine riesige Logdatei, löscht sie mit rm, und der Dienst, der hineinschreibt, läuft einfach weiter. Er schreibt fröhlich in eine Datei, die es im Verzeichnis nicht mehr gibt, und die Platte wird weiter voller.

So findest du solche Dateien

sudo lsof -nP +L1

+L1 heißt: Zeige offene Dateien mit weniger als einem Link, also gelöschte. In unserem Test kam genau eine Zeile:

sleep  4082618  root  3r  REG  7,3  104857600  0  12  /tmp/gmdisk/mnt/big.log (deleted)

Du siehst Prozessname, PID, Dateideskriptor (hier 3), Größe (100 MB) und den alten Pfad mit dem Zusatz (deleted). Auf unserem Produktivserver lieferte derselbe Befehl übrigens 425 Einträge, die zusammen rund 48 MB belegten. Das ist harmlos und normal, viele Programme arbeiten absichtlich mit gelöschten Temp-Dateien. Verdächtig wird es, wenn ein einzelner Eintrag Gigabytes groß ist.

Ist lsof nicht installiert, geht es auch ohne:

sudo find /proc/*/fd -ls 2>/dev/null | grep '(deleted)'

So bekommst du den Platz zurück

Die sauberste Lösung ist, den Dienst neu zu starten (systemctl restart dienstname) oder ihm zu sagen, dass er seine Logdatei neu öffnen soll (bei vielen Diensten über systemctl reload oder ein Signal wie SIGHUP oder SIGUSR1). Wenn ein Neustart gerade nicht geht, kannst du die Datei über den Prozess leeren:

# PID und FD aus der lsof-Ausgabe
sudo sh -c ': > /proc/4082618/fd/3'

In unserem Test sprang die Belegung damit sofort von 64 auf 1 Prozent, ohne dass der Prozess beendet wurde. Das ist ein Notbehelf: Der Prozess schreibt danach weiter in die (jetzt leere) gelöschte Datei, das Problem kommt also langsam zurück, bis du den Dienst sauber neu startest.

Die Regel für die Zukunft: Eine Logdatei, die gerade benutzt wird, nie mit rm löschen, sondern leeren:

sudo truncate -s 0 /var/log/meinedienst/gross.log

So bleibt die Datei bestehen, der Dienst schreibt einfach weiter hinein, und der Platz ist sofort frei.

Schritt 5: Reservierte Blöcke, warum root noch schreiben kann

Erinnerst du dich an die Lücke zwischen 451 GB Größe, 400 GB belegt und nur 33 GB frei? Das sind die reservierten Blöcke. ext4 reserviert beim Anlegen standardmäßig 5 Prozent der Blöcke für root. In unserem 200-MB-Testsystem waren das laut tune2fs exakt 2.560 von 51.200 Blöcken.

Wir haben das ausprobiert. Zuerst haben wir als normaler Benutzer (nobody) geschrieben, bis nichts mehr ging:

dd: error writing 'mnt/fill': No space left on device
/dev/loop3      172M  158M     0 100% /tmp/gmdisk/mnt

df meldete 100 Prozent und 0 frei. Danach schrieb root auf dasselbe Dateisystem noch einmal rund 10 MB, bis auch für ihn Schluss war. Die Belegung stieg von 158 auf 168 MB.

Das ist Absicht, kein Fehler. Die Reserve sorgt dafür, dass Systemdienste, die als root laufen, und du als Admin noch handeln können, wenn normale Benutzer die Platte vollgeschrieben haben. Daraus folgen zwei praktische Dinge:

  • Wenn eine Anwendung (als eigener Benutzer) „No space left“ meldet, aber root noch Dateien anlegen kann, ist die Platte für die Anwendung trotzdem voll. Die Reserve ist kein Puffer für deine Dienste.
  • Auf großen reinen Datenplatten (etwa für Backups oder Medien), auf denen kein Betriebssystem liegt, sind 5 Prozent viel. Bei 4 TB sind das 200 GB. Dort kannst du die Reserve senken: sudo tune2fs -m 1 /dev/sdb1. Auf der Systempartition solltest du sie lassen.

XFS kennt diese Reserve für root nicht in derselben Form. Dort ist voll wirklich voll, für alle.

Falle: Eine volle Platte kann Konfigdateien leeren

Diese Falle wird in fast keiner Anleitung erwähnt, und sie kann aus einem lästigen Problem ein echtes machen. Wir haben auf dem vollen Testdateisystem eine kleine Konfigdatei mit zwei Zeilen angelegt und dann versucht, sie mit neuem Inhalt zu überschreiben, genau so, wie es ein Editor, ein Skript oder ein Deployment-Tool täte:

$ cat app.conf
port=8080
name=app
$ printf 'port=9090\nname=app\nfoo=bar\n' > app.conf
printf: I/O error
$ ls -l app.conf
-rw-rw-rw- 1 root root 0  app.conf

Die Datei hat danach null Byte. Das liegt daran, wie die Umleitung > arbeitet: Die Shell öffnet die Datei zuerst zum Schreiben und kürzt sie dabei auf null. Erst danach wird der neue Inhalt geschrieben, und genau das scheitert, weil kein Platz da ist. Das Ergebnis ist weder die alte noch die neue Konfiguration, sondern gar keine.

Dasselbe passiert mit Programmen, die ihre Statusdatei oder Konfiguration ständig neu schreiben. Startet ein Dienst danach mit einer leeren Konfiguration neu, fällt er womöglich mit Standardwerten an, oder gar nicht. Deshalb gilt:

  • Auf einer vollen Platte nichts überschreiben, was du nicht verlieren willst. Erst Platz schaffen, dann ändern.
  • In eigenen Skripten Dateien atomar schreiben: Inhalt in eine Temp-Datei im selben Ordner schreiben, prüfen, dass das geklappt hat, und dann mit mv umbenennen. mv ersetzt die Datei in einem Schritt, die alte bleibt erhalten, bis die neue vollständig ist.
tmp=$(mktemp ./app.conf.XXXX) && printf '...' > "$tmp" && mv "$tmp" app.conf

Nach einem Vollaufen solltest du deshalb nicht nur Platz freiräumen, sondern auch prüfen, ob irgendwo Konfigurationen oder Datenbankdateien leer oder beschädigt sind. find /etc -xdev -type f -size 0 -newermt '-2 hours' zeigt dir zum Beispiel alle Dateien in /etc, die in den letzten zwei Stunden geändert wurden und jetzt leer sind.

Falle: Daten unter einem Mountpoint

Der letzte Fall, in dem df und du sich widersprechen, ist selten, aber besonders tückisch. Wir haben auf unserem Testdateisystem einen Ordner data angelegt, darin eine 80-MB-Datei geschrieben und danach ein zweites Dateisystem genau auf diesen Ordner eingehängt:

$ df -h mnt
/dev/loop3      172M   81M   78M  51% /tmp/gmdisk/mnt
$ du -shx mnt
20K	mnt

81 MB belegt, aber du findet nur 20 KB. Die Datei liegt noch auf der Platte, ist aber vom neuen Mount verdeckt. Kein ls und kein du sieht sie, solange der Mount besteht.

Das passiert in echt vor allem, wenn ein Laufwerk beim Booten einmal nicht eingehängt wurde, etwa eine Backup-Platte oder ein Netzlaufwerk. Dann schreibt ein Backup-Job oder eine Anwendung in den leeren Mountpoint-Ordner auf der Systemplatte. Beim nächsten Neustart ist das Laufwerk wieder da und verdeckt die Daten. Die Systemplatte ist voller, und niemand weiß, warum.

Finden kannst du das mit einem Bind-Mount, der die Systempartition noch einmal ohne die darüberliegenden Mounts zeigt:

sudo mkdir -p /mnt/rootview
sudo mount --bind / /mnt/rootview
sudo du -sh /mnt/rootview/mnt/* /mnt/rootview/media/* 2>/dev/null
sudo umount /mnt/rootview

In unserem Test zeigte der Bind-Mount die versteckten 81 MB sofort. Gegen das Problem hilft in /etc/fstab die Option nofail zusammen mit Diensten, die prüfen, ob ihr Ziel wirklich ein Mountpoint ist (mountpoint -q /backup || exit 1), bevor sie schreiben.

Die üblichen Platzfresser auf einem Linux-Server

Wenn keine der Fallen zutrifft, ist es fast immer einer dieser Kandidaten. Bei uns haben wir alle gemessen.

Das systemd-Journal

journalctl --disk-usage

Bei uns: 390,8 MB. Das ist harmlos, weil wir in /etc/systemd/journald.conf eine Grenze gesetzt haben (SystemMaxUse=1G). Ohne Grenze nimmt sich journald bis zu 10 Prozent des Dateisystems, maximal 4 GB. Auf einem kleinen VPS mit 20 GB sind das schnell 2 GB nur für Logs. Aufräumen geht sofort und sicher:

sudo journalctl --vacuum-size=500M    # auf 500 MB kürzen
sudo journalctl --vacuum-time=14d     # alles älter als 14 Tage weg

Damit es dauerhaft bleibt, die Grenze in der Konfiguration setzen und sudo systemctl restart systemd-journald ausführen.

Docker: Images, Container, Volumes und Logs

Docker ist auf vielen Servern der größte einzelne Platzverbraucher, und gleichzeitig der, bei dem falsches Aufräumen am meisten Schaden anrichtet. Erst schauen:

docker system df

Bei uns:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          15        6         16.16GB   4.551GB (28%)
Containers      8         8         1.065GB   0B (0%)
Local Volumes   4         4         2.103GB   0B (0%)
Build Cache     5         0         79.8MB    0B

4,5 GB könnten weg, nämlich Images, die kein Container mehr benutzt. Dafür gibt es abgestufte Befehle:

docker image prune        # nur "dangling" Images (ohne Tag)
docker image prune -a     # alle Images ohne laufenden oder gestoppten Container
docker builder prune      # Build-Cache

Vorsicht bei docker system prune --volumes. Dieser Befehl löscht zusätzlich alle Volumes, die gerade an keinen Container hängen. Hast du einen Datenbank-Container gestoppt, um ihn neu aufzusetzen, ist das Volume mit seinen Daten in diesem Moment „unbenutzt“, und weg. Wir verwenden auf unseren Servern deshalb grundsätzlich kein pauschales prune mit --volumes, sondern löschen Volumes nur einzeln und mit Namen.

Ein oft übersehener Platzfresser sind die Container-Logs. Der Standard-Logtreiber json-file schreibt ohne Grenze nach /var/lib/docker/containers/<id>/<id>-json.log. Ein gesprächiger Container kann damit über Monate viele Gigabyte füllen. Abhilfe in /etc/docker/daemon.json:

{
  "log-driver": "json-file",
  "log-opts": { "max-size": "50m", "max-file": "3" }
}

Die Einstellung gilt nur für neu erstellte Container. Bestehende musst du einmal neu anlegen (docker compose up -d --force-recreate). Mehr zu den Grundlagen steht in unserem Artikel Was ist Docker?.

Paket-Cache und alte Kernel

du -sh /var/cache/apt     # bei uns 620 MB
sudo apt clean            # Paket-Cache leeren
sudo apt autoremove --purge   # nicht mehr benötigte Pakete, inkl. alter Kernel

apt clean ist völlig gefahrlos, die Pakete werden bei Bedarf neu geladen. apt autoremove solltest du vorher ohne -y laufen lassen und die Liste lesen. Bei Fedora und RHEL heißen die Gegenstücke dnf clean all und dnf autoremove. Auf Ubuntu-Systemen mit Snap kann zusätzlich /var/lib/snapd mit alten Revisionen wachsen. sudo snap set system refresh.retain=2 begrenzt die Zahl der aufgehobenen Versionen.

Wenn /boot eine eigene kleine Partition ist, läuft gerade sie gern voll, weil sich alte Kernel ansammeln. Dann scheitern Updates mit kryptischen Fehlern. autoremove löst das in fast allen Fällen.

Logdateien in /var/log

Bei uns belegte /var/log knapp 1 GB, das ist unauffällig. Problematisch wird es, wenn ein Dienst eigene Logs schreibt, die von logrotate nicht erfasst werden, oder wenn ein Fehler in einer Schleife tausende Zeilen pro Sekunde ins Log schreibt. Dann hilft kein Aufräumen, sondern nur, den Fehler zu beheben. Ein schneller Blick auf die größten Logs:

sudo find /var/log -type f -size +100M -exec ls -lh {} \;

Rotierte und komprimierte Altlogs (*.gz, *.1) kannst du gefahrlos löschen, die aktuelle Datei leerst du mit truncate, wie oben beschrieben.

Datenbanken: Binlogs und WAL

MySQL und MariaDB schreiben mit aktiviertem Binärlog jede Änderung zusätzlich in binlog-Dateien. Ohne Ablaufzeit wachsen die unbegrenzt. Nie mit rm löschen, sondern über die Datenbank:

PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;

Dauerhaft setzt du binlog_expire_logs_seconds (MySQL 8) bzw. expire_logs_days (ältere MariaDB). Wie Binlogs mit Backups und Point-in-Time-Recovery zusammenhängen, haben wir im Artikel MySQL Backup ausführlich gemessen. Bei PostgreSQL ist es meist ein hängender Replikations-Slot, der WAL-Dateien festhält. SELECT slot_name, active FROM pg_replication_slots; zeigt, ob ein inaktiver Slot schuld ist.

Backups am falschen Ort

Ein Klassiker, den wir selbst kennen: Ein Backup-Skript schreibt jede Nacht ein Archiv auf dieselbe Platte, die es sichern soll, und löscht nie alte Stände. Das ist doppelt schlecht, weil es die Platte füllt und gleichzeitig kein echtes Backup ist. Ein Backup, das mit dem Server zusammen kaputtgeht, schützt vor nichts. Wie man es richtig aufteilt, steht in unserer 3-2-1-Backup-Strategie.

Temp-Ordner, Core-Dumps und Home-Verzeichnisse

/tmp belegte bei uns 9,7 GB, vor allem durch Build-Ordner und Testdaten, die nach dem Zweck liegen geblieben waren. Viele Distributionen räumen /tmp nur beim Neustart, Server werden aber selten neu gestartet. systemd-tmpfiles kann alte Dateien automatisch entfernen (Konfiguration in /etc/tmpfiles.d/). Abgestürzte Programme hinterlassen außerdem Core-Dumps, die mehrere Gigabyte groß sein können. coredumpctl list zeigt sie, /var/lib/systemd/coredump/ ist der übliche Ort.

Und dann sind da die Home-Verzeichnisse. Bei uns lag mit 306 GB der mit Abstand größte Brocken unter /root, wo Projekte, Build-Artefakte und Arbeitskopien wohnen. Das ist kein Fehler, sondern Arbeitsmaterial, und genau deshalb das Beispiel dafür, warum man auf einem Server nicht blind löschen sollte.

Sicher aufräumen: was du löschen darfst und was nicht

Beim Aufräumen unter Zeitdruck passieren die teuersten Fehler. Unsere Faustregeln, aus Erfahrung und nach dem September-Vorfall noch einmal geschärft:

Gefahrlos:

  • apt clean / dnf clean all
  • journalctl --vacuum-size=…
  • rotierte Logs (*.gz, *.1, *.old) in /var/log
  • docker image prune und docker builder prune
  • Core-Dumps, wenn du sie nicht für eine Fehleranalyse brauchst

Mit Nachdenken:

  • apt autoremove: Liste lesen, bevor du bestätigst
  • docker image prune -a: Images werden beim nächsten Start neu geladen, das kostet Zeit und Bandbreite
  • Inhalte von /tmp: erst prüfen, ob gerade ein Prozess damit arbeitet (lsof +D /tmp/ordner)
  • alte Backups: nur, wenn eine neuere, geprüfte Kopie an einem anderen Ort existiert

Nicht anfassen:

  • Dateien von laufenden Datenbanken (/var/lib/mysql, /var/lib/postgresql) direkt mit rm
  • Docker-Volumes pauschal per prune --volumes
  • Binlogs oder WAL-Dateien mit rm
  • alles unter /usr, /lib, /boot (außer über den Paketmanager)

Und unabhängig davon: Bevor du etwas löschst, das du nicht selbst angelegt hast, frag dich, ob ein Dienst darauf angewiesen ist. Ein Ordner, der riesig ist, ist nicht automatisch Müll.

Ein Roboterarm sortiert in einem aufgeräumten Serverraum alte, matte Blöcke aus, während die leuchtenden ordentlich gestapelt bleiben

Notfall: Die Platte ist zu 100 Prozent voll und nichts geht mehr

Wenn wirklich nichts mehr geht, also auch apt und Editoren streiken, hilft diese Reihenfolge:

  1. Ruhe bewahren und nichts überschreiben. Keine Konfigurationen bearbeiten, keine Dienste neu konfigurieren (siehe die Falle mit den leeren Dateien).
  2. Schnell ein paar Hundert MB freimachen: journalctl --vacuum-size=200M, apt clean, einen großen rotierten Log löschen. Das verschafft Luft für alles Weitere.
  3. Gelöschte offene Dateien prüfen: lsof +L1. Oft liegt hier sofort die Lösung.
  4. Dann in Ruhe suchen mit du oder dem jetzt installierbaren ncdu.
  5. Danach prüfen, was beim Vollaufen kaputtgegangen ist: leere Dateien in /etc, Datenbank-Logs auf Fehler, Dienste per systemctl --failed.

Kommst du gar nicht mehr per SSH auf den Server, weil auch die Anmeldung Schreibzugriff braucht, bleibt die Rettungskonsole deines Hosters oder ein Rescue-System. Dort hängst du die Platte ein und räumst von außen auf.

Ein Trick, den viele Admins vorbeugend einsetzen: eine Platzhalter-Datei, etwa fallocate -l 2G /var/reserve.img. Läuft die Platte voll, löschst du sie und hast sofort 2 GB Luft für die Rettung. Das ist simpel, kostet aber eben auch dauerhaft 2 GB.

Damit es nicht wieder passiert

Die eigentliche Lösung ist nicht das Aufräumen, sondern dass du rechtzeitig Bescheid bekommst. Drei Dinge reichen auf den meisten Servern:

1. Grenzen für alles, was wächst. journald mit SystemMaxUse, Docker mit max-size, Datenbanken mit Ablaufzeiten für Binlogs, eigene Logs über logrotate, Backups mit fester Aufbewahrung.

2. Eine Warnung bei 80 bis 85 Prozent. Das kann ein vollwertiges Monitoring sein, wie wir es im Artikel Server Monitoring verglichen haben, oder ein kleines Skript per Cronjob:

#!/bin/sh
# /usr/local/bin/disk-warn.sh
LIMIT=85
df -P -x tmpfs -x devtmpfs -x overlay | awk -v l=$LIMIT 'NR>1 {gsub("%","",$5); if ($5 >= l) print $6": "$5"%"}' | \
while read line; do
  echo "Platte fast voll auf $(hostname): $line" | mail -s "Disk-Warnung $(hostname)" admin@example.com
done

Wichtig ist, auch die Inodes zu überwachen (df -iP analog), sonst übersieht die Warnung genau den Fall aus unserem Test. Wie du so ein Skript zeitgesteuert laufen lässt, steht in unserer Anleitung Cronjob erstellen.

3. Ein Blick auf den Trend statt nur auf den Moment. Eine Platte, die jeden Tag um 1 GB wächst, ist bei 70 Prozent gefährlicher als eine, die seit Monaten bei 90 Prozent steht. Wer die Belegung einmal am Tag in eine Datei schreibt (df -h / >> /var/log/disk-trend.log), sieht Ausreißer, lange bevor sie zum Problem werden.

Und schließlich die vielleicht wichtigste Regel: Prüfe nach jedem Aufräumen mit df -h, ob der Platz wirklich frei geworden ist. Wenn nicht, ist es fast immer eine gelöschte, noch offene Datei, oder du hast auf dem falschen Dateisystem aufgeräumt.

Häufige Fragen zu „Linux Festplatte voll“

Wie prüfe ich unter Linux, wie voll die Festplatte ist? Mit df -h. Der Befehl zeigt für jedes eingehängte Dateisystem Größe, Belegung und freien Platz. Für einen bestimmten Ordner nimmst du df -h /pfad, für die Inodes df -i.

Warum ist die Platte voll, obwohl du kaum Daten findet? Meistens hält ein laufender Prozess eine bereits gelöschte Datei offen. sudo lsof +L1 zeigt solche Dateien. Seltener liegen Daten unter einem Mountpoint versteckt oder der Unterschied besteht aus den reservierten Blöcken von ext4.

Warum meldet Linux „No space left on device“, obwohl df noch freien Platz zeigt? Dann sind sehr wahrscheinlich die Inodes erschöpft. Prüfe mit df -i. In unserem Test meldete ein Dateisystem bei 1 Prozent Belegung und 55 MB frei bereits „voll“, weil alle 2.000 Inodes verbraucht waren.

Was ist der Unterschied zwischen df und du? df fragt das Dateisystem, wie viele Blöcke belegt sind. du läuft durch die Verzeichnisse und summiert die Größen der Dateien, die es findet. Gelöschte offene Dateien und verdeckte Daten unter Mounts zählt nur df.

Wie finde ich die größten Ordner unter Linux? sudo du -xh --max-depth=1 / | sort -rh | head zeigt die größten Ordner auf oberster Ebene. Komfortabler ist sudo ncdu -x /, damit kannst du dich interaktiv durch die Ordner klicken.

Darf ich journalctl-Logs einfach löschen? Nicht mit rm, aber mit journalctl --vacuum-size=500M oder --vacuum-time=14d. Das entfernt nur alte, abgeschlossene Journaldateien und ist gefahrlos. Für eine dauerhafte Grenze setzt du SystemMaxUse in /etc/systemd/journald.conf.

Wie räume ich Docker sicher auf? Zuerst docker system df ansehen. Dann docker image prune und docker builder prune für gefahrloses Aufräumen. Vermeide docker system prune --volumes, weil das Volumes gestoppter Container mitsamt ihren Daten löscht.

Warum kann root noch schreiben, normale Benutzer aber nicht mehr? ext4 reserviert standardmäßig 5 Prozent der Blöcke für root, damit Systemdienste und Admins bei voller Platte noch handeln können. Auf reinen Datenplatten kannst du die Reserve mit tune2fs -m 1 senken.

Kann eine volle Festplatte Daten beschädigen? Ja. Programme, die eine Datei beim Speichern erst leeren und dann neu schreiben, hinterlassen bei voller Platte eine leere Datei. In unserem Test hatte eine Konfigdatei danach null Byte. Datenbanken sind meist robuster, können aber den Dienst einstellen, bis wieder Platz da ist.

Wie verhindere ich, dass die Festplatte wieder vollläuft? Grenzen für Logs und Caches setzen (journald, Docker, Binlogs, logrotate), Backups nicht auf derselben Platte lagern und eine Warnung bei 80 bis 85 Prozent einrichten, für Bytes und Inodes.

Fazit: Linux Festplatte voll ist meistens kein Rätsel, wenn du in der richtigen Reihenfolge suchst

Eine volle Festplatte unter Linux wirkt im ersten Moment chaotisch, folgt aber fast immer denselben Mustern. df -h sagt dir, welches Dateisystem es trifft, df -i, ob es Bytes oder Inodes sind, du und ncdu zeigen dir den Ordner, und lsof +L1 erklärt die Fälle, in denen die Zahlen nicht zusammenpassen.

Aus unseren Tests nehmen wir drei Dinge mit, die in kaum einer Kurzanleitung stehen. Erstens: Eine gelöschte Datei ist erst frei, wenn niemand sie mehr offen hält, und eine aktive Logdatei leert man deshalb mit truncate statt mit rm. Zweitens: „Voll“ kann bei 1 Prozent Belegung passieren, wenn die Inodes aus sind. Drittens: Eine volle Platte ist nicht nur lästig, sie kann Konfigdateien beim Speichern auf null Byte schrumpfen lassen. Wer daran denkt, räumt erst auf und ändert dann.

Wenn du gerade einen neuen Server aufsetzt, ist jetzt der beste Moment, die Grenzen und die Warnung gleich mit einzurichten. Wie das in den Rest der Grundeinrichtung passt, zeigen wir in unserer Anleitung Linux-Server einrichten.