Uns ist aufgefallen, dass in MinIO ein Ordner manchmal auch nach einem Klick auf „Delete Folder“ in der Weboberfläche weiterhin angezeigt wird – und schlimmer noch: Er lässt sich anschließend überhaupt nicht mehr löschen. Schauen wir uns dieses Problem genauer an.1
Aktuelle Situation
Wir verwenden Spark, um Parquet-Dateien nach MinIO (RELEASE.2025-03-12T17-29-24Z) zu schreiben. Irgendwann begann Delta Lake folgenden Fehler auszugeben:
Caused by: org.apache.spark.sql.delta.DeltaAnalysisException: [DELTA_CREATE_TABLE_WITH_NON_EMPTY_LOCATION]
Cannot create table ('`landingzone`.`testi_table`'). The associated location ('s3a://landing-zone/testi/table') is not empty and also not a Delta table.
Als wir den entsprechenden Pfad in der MinIO-Weboberfläche überprüften, konnten wir den Ordner jedoch nicht löschen. Darin befanden sich „Ordner“ mit der Endung .parquet, die jedoch leer zu sein schienen. Da sich diese nicht entfernen ließen, betrachtete Delta den Speicherort weiterhin als nicht leer und verweigerte die Erstellung der Tabelle.
Analyse
MinIO speichert Objekte auf Dateisystemebene anders, als sie in der Weboberfläche dargestellt werden.
Ein intaktes Objekt (z. B. eine Parquet-Datei) sieht folgendermaßen aus:
part-00000-...snappy.parquet/
├── xl.meta
└── <uuid>/
├── part.1
├── part.2
└── part.3
Auffällig ist die Datei xl.meta. Sie lässt sich zwar teilweise lesen, enthält jedoch auch nicht lesbare Zeichen und Symbole. Das deutet darauf hin, dass es sich um eine Binärdatei handelt, die Metadaten enthält und MinIO beschreibt, wie das Verzeichnis als einzelnes Objekt interpretiert werden soll.
In unserem fehlerhaften Fall sah die Struktur dagegen so aus:
part-00000-...snappy.parquet/
└── <uuid>/
└── part.1
Hier fehlt die Datei xl.meta!
Unsere Interpretation / Hypothese
Ohne xl.meta kann MinIO dieses Verzeichnis offenbar nicht mehr als Objekt interpretieren. Dadurch entsteht folgendes Verhalten:
- Die Weboberfläche zeigt das Verzeichnis als Ordner an (weil es auf Dateisystemebene tatsächlich ein Ordner ist).
- Der Ordner erscheint jedoch leer, da MinIO die rohen Datenfragmente nicht mehr interpretieren kann.
mc-Befehle funktionieren nicht mehr zuverlässig.- Spark bzw. Delta erkennt dennoch, dass sich irgendetwas an diesem Speicherort befindet, wodurch die oben genannten Fehler ausgelöst werden.
Vermutlich entsteht dieser Zustand durch einen unterbrochenen Schreib- oder Löschvorgang, bei dem verwaiste Datenfragmente ohne die zugehörigen Metadaten zurückbleiben.


Lösung
Die einzige zuverlässige Lösung bestand darin, die beschädigten Objekte direkt auf Dateisystemebene zu entfernen. MinIO erlaubte dies, ohne dass ein Neustart des Containers erforderlich war. Anschließend war der Speicherort tatsächlich leer und Delta konnte die Tabelle wieder erfolgreich anlegen.
Wir haben außerdem verschiedene Ansätze mit dem MinIO-Client (mc) ausprobiert und unterschiedliche Optionen wie --version, --dangerous und --force getestet. Keiner dieser Ansätze war jedoch erfolgreich.
Weitere (verwandte) Resourcen
https://github.com/minio/minio/discussions/15257#discussioncomment-3109625
https://github.com/minio/minio/issues/16836
https://github.com/minio/minio/discussions/19516
- This blog post was drafted manually and then summarized, refined, and written with the help of ChatGPT 5.3. ↩︎
