Sicherheitsgrundlagen
Supabase "Bucket not found": die drei Dinge, die es bedeutet
Supabase "Bucket not found" ist eins von drei Dingen: ein öffentlicher Link zu einem privaten Bucket, ein ungenauer Name oder das falsche Projekt.

Kurz gesagt
- Supabase "Bucket not found" heißt, dass Storage nach einem Bucket mit genau diesem Namen gesucht hat, in dem Projekt, das deine Anfrage erreicht hat, und keinen gefunden hat, den es dieser Anfrage ausliefern würde. Der Bucket kann trotzdem in deinem Dashboard stehen.
- Ein Link, den getPublicUrl für einen privaten Bucket gebaut hat, liefert beim Öffnen genau diesen Fehler, weil Storage solche Links nur aus öffentlichen Buckets bedient.
- Bei einem Upload heißt es, dass der Name in diesem Projekt fehlt. Prüf die Schreibweise und die Großbuchstaben, dann, auf welches Projekt deine App zeigt.
- Den Bucket öffentlich zu machen beendet die Meldung und lässt jeden, der die Adresse einer Datei hat, diese Datei öffnen. Für Dateien, die einer Person gehören, nimm einen signierten Link.
Deine App zeigt ein kaputtes Bild, wo ein Foto sein sollte. Oder ein Upload scheitert, und die Meldung, die zurückkommt, ist drei Wörter lang: "Bucket not found". Dann öffnest du Supabase, gehst zu Storage, und der Bucket steht genau da in der Liste.
Öffne die Adresse des Bildes in einem eigenen Tab, und Storage antwortet so:
{
"statusCode": "404",
"code": "NoSuchBucket",
"error": "Bucket not found",
"message": "Bucket not found"
}
Das ist der Body, den der Quellcode von Supabase Storage heute baut, gelesen am 17. Oktober 2026. Supabase "Bucket not found" deckt mit diesem einen Body drei verschiedene Situationen ab, und in der ersten liegt der Bucket genau dort, wo du ihn gelassen hast.
Und hier liegt Ratgeber um Ratgeber falsch: die erste Lösung, die du findest, ist, den Bucket öffentlich zu machen, und wenn sie funktioniert, dann weil damit jede Datei in diesem Bucket ebenfalls öffentlich wird. Bei zwei der drei Ursachen ändert sie überhaupt nichts. Bei der übrigen tauscht sie ein kaputtes Bild gegen einen Bucket, aus dem jeder lesen kann, der die Adresse einer Datei hat.
Was bedeutet Supabase "Bucket not found"?
Storage hat nach einem Bucket mit genau dem Namen aus deiner Anfrage gesucht, in dem Projekt, das deine Anfrage erreicht hat, und keinen gefunden, den es dieser Anfrage ausliefern würde.
Der letzte Teil steht da, weil ein Bucket mehr als eine Tür hat und jede Tür die Frage auf ihre eigene Weise stellt. Der Quellcode von Storage zeigt drei davon:
- Eine öffentliche Dateiadresse, wie
getPublicUrlsie baut. Diese Tür zählt nur Buckets, die als öffentlich markiert sind, also ist ein privater Bucket hier "nicht gefunden", obwohl es ihn gibt. - Ein Upload. Diese Tür zählt jeden Bucket im Projekt, private eingeschlossen. "Nicht gefunden" heißt hier, dass dieser Name in diesem Projekt wirklich fehlt.
- Eine Anfrage nach der Dateiliste eines Buckets. Diese Tür sagt nie "Bucket not found". Ein Bucket, den es nicht gibt, antwortet mit einer leeren Liste, derselben Antwort wie ein leerer Bucket, und das sehen wir von außen jedes Mal, wenn unser Scanner fragt.
Die erste Aufgabe ist also herauszufinden, durch welche Tür die gescheiterte Anfrage kam.
Die zwei Zahlen in dieser Meldung widersprechen sich, und das bringt die
Fehlerbehandlung durcheinander. Der Body sagt "statusCode": "404", während
die Anfrage selbst mit dem HTTP-Status 400 scheitert. Storage schickt diesen
Fehler mit einer 400 und behält seine eigene 404 im Body. Die Bibliothek
supabase-js reicht beides an deinen Code weiter: error.status ist 400 und
error.statusCode ist "404". Code, den dein Builder geschrieben hat, um eine
404 abzufangen, lässt diesen Fehler einfach vorbei.
Ursache 1: ein öffentlicher Link zu einem privaten Bucket
Das ist die Ursache hinter kaputten Bildern. Die Adresse wurde für einen öffentlichen Bucket gebaut, und der Bucket ist privat.
getPublicUrl fragt Supabase gar nichts. Es setzt die Adresse deines Projekts,
den Bucket-Namen und den Dateinamen zu einem Link zusammen, in deiner App, und
gibt ihn zurück. Der Hinweis über dieser Funktion in Supabases eigener
Client-Bibliothek sagt das in zwei Sätzen:
Diese Funktion prüft nicht, ob der Bucket öffentlich ist. Wird eine öffentliche URL für einen Bucket erzeugt, der nicht öffentlich ist, kannst du die Datei nicht herunterladen.
Später fragt der Browser eines Besuchers nach diesem Link, und Storage sucht den Bucket nur unter den öffentlichen Buckets. Ein privater Bucket fällt bei dieser Suche genauso durch wie ein fehlender, und die Antwort lautet "Bucket not found".
Du erkennst diese Ursache am Link selbst. Eine öffentliche Dateiadresse enthält
/storage/v1/object/public/, gefolgt vom Bucket-Namen. Trägt dieser Bucket in
Storage → Buckets keine Markierung als öffentlich, konnte sich der Link nie
öffnen, egal wie der Name geschrieben ist.
Neue Buckets starten privat, die Einstellung verhält sich also wie vorgesehen. Passiert ist, dass Code für einen öffentlichen Bucket geschrieben und auf einen privaten gerichtet wurde, von dir oder von deinem Builder.
Ursache 2: ein Name, der nicht ganz der Name des Buckets ist
Storage vergleicht den Bucket-Namen Zeichen für Zeichen, also sind Avatars und
avatars zwei verschiedene Buckets, und avatar und avatars ebenso.
Im Quellcode von Storage ist die Suche ein schlichter Gleichheitsvergleich auf die id des Buckets. Großbuchstaben zählen, ein fehlender Buchstabe zählt, und ein Bindestrich, wo der Bucket einen Unterstrich hat, zählt. Jeder dieser Fälle kommt als dieselben drei Wörter zurück.
Eine App, die mit einem KI-Werkzeug gebaut wurde, kann hier landen, ohne dass sich irgendwer vertippt hat. Der Code, der eine Datei hochlädt oder anzeigt, entsteht in einem Schritt, und der Bucket, den er nennt, soll in einem anderen angelegt werden. Lief dieser zweite Schritt nie, oder lief er mit einem leicht anderen Namen, fragt der Code nach einem Bucket, den niemand angelegt hat.
Die Prüfung braucht zwei Listen. Öffne Storage → Buckets und notier dir den Namen jedes Buckets genau so, wie er dort steht. Dann sag deinem Builder in einfachen Worten: Liste jeden Storage-Bucket-Namen auf, den diese App benutzt, und zeig mir, wo jeder davon benutzt wird. Jeder Name auf seiner Liste, der auf deiner fehlt, ist der, der scheitert.
Ursache 3: der Bucket liegt in einem anderen Projekt
Deine App spricht mit genau einem Supabase-Projekt, dem in ihrer Supabase-Adresse, und ein Bucket, der in irgendeinem anderen Projekt angelegt wurde, existiert für deine App schlicht nicht.
Am deutlichsten zeigt sich diese Ursache bei einem Upload. Bei einem Upload sucht Storage den Bucket im ganzen Projekt, ohne deine Zugriffsregeln anzuwenden, also ist "Bucket not found" bei einem Upload nie ein Berechtigungsproblem. Wenn der Bucket existiert und deine Regeln die Datei ablehnen, antwortet Storage mit einer anderen Meldung über Row-Level Security. "Bucket not found" bei einem Upload heißt also, dass dieser Name in dem Projekt fehlt, in das deine App schreibt.
Es gibt ganz gewöhnliche Wege zu zwei Projekten: ein Testprojekt neben dem Live-Projekt, eine Kopie der App, die mit einem frischen Projekt verbunden wurde, ein Projekt, das jemand von Hand angelegt hat, um etwas auszuprobieren. Der Bucket landet in dem, das gerade im Dashboard offen war.
Die Prüfung ist ein Vergleich zweier kurzer Zeichenfolgen. Die Supabase-Adresse
deiner App sieht aus wie https://<ref>.supabase.co, und der Teil vor
.supabase.co ist die Referenz des Projekts. Die Adresse deines Dashboards
trägt dieselbe Referenz nach /project/. Weichen die beiden ab, schaust du auf
ein Projekt, während deine App mit einem anderen spricht.
Solltest du den Bucket öffentlich machen, um es zu beheben?
Nur wenn jede Datei im Bucket für jeden gedacht ist, der ihre Adresse hat, und nur bei der ersten Ursache. Bei einem falschen Namen oder einem falschen Projekt ändert der Schalter gar nichts.
Ein öffentlicher Bucket tut eine Sache, und Supabases Dokumentation beschreibt sie in einer Zeile: Jeder, der die Adresse einer Datei besitzt, kann sie öffnen. Eine Anmeldung kommt dabei nicht vor. Supabases eigene Beispiele dafür sind Profilbilder, öffentliche Medien und Inhalte von Blogbeiträgen, und Logos oder Produktfotos gehören in dieselbe Gruppe.
Für Rechnungen, Ausweisscans, Exporte oder alles, was einer Person gehört, ist es die falsche Einstellung. Der Schalter gilt für den ganzen Bucket und für jede Datei, die später dort landet, auch für Dateien aus einer Funktion, die du noch gar nicht gebaut hast.
Dieselbe Abkürzung hat einen Zwilling auf der Seite der Regeln, und den messen
wir. Eine Regel auf storage.objects, die nur den Bucket nennt, lässt
Downloads für alle funktionieren und gibt außerdem die Liste der Namen im Bucket
heraus. Wir haben 8.435 lebende Apps gescannt, die ein Supabase-Projekt nennen.
Bei 4.703 davon hat die Bucket-Prüfung eine Antwort bekommen, und 792 haben
unsere Listenanfrage mit den Namen dessen beantwortet, was drinlag, ohne dass
jemand angemeldet war. Das ist etwa eine von sechs der Apps, die wir fragen
konnten. Ist ein Bucket öffentlich und seine Liste ebenfalls offen, dann ist
jeder Name auf dieser Liste ein funktionierender Link.
Wie du eine private Datei zeigst, ohne sie öffentlich zu machen
Gib der Seite einen signierten Link: eine Adresse, die für eine Anzahl Sekunden funktioniert, die du festlegst, und danach aufhört zu funktionieren.
Supabases Dokumentation nennt zwei Wege, eine Datei aus einem privaten Bucket zu
holen. Der eine ist ein Download, der die Sitzung der angemeldeten Person
mitschickt. Der andere ist createSignedUrl, das einen Link baut, "auf den für
eine begrenzte Zeit zugegriffen werden kann". Dieser zweite tritt überall an die
Stelle von getPublicUrl, wo eine Seite ein Bild zeigt.
Auch ein signierter Link unterliegt deinen Regeln. Bevor Storage irgendetwas
signiert, prüft sein Quellcode, ob die anfragende Person diese Datei lesen darf,
also braucht ein privater Bucket eine select-Regel auf storage.objects, die
festlegt, wer was lesen darf.
Der Upload-Fehler erklärt, wie solche Regeln geschrieben werden,
auch, warum eine Leseregel, die nur den Bucket nennt, zugleich seine Liste
öffnet.
Um das an deinen Builder zu geben, in einfachen Worten: Ersetze für den Bucket hinter dem Fehler "Bucket not found" getPublicUrl durch createSignedUrl, lass den Bucket privat und füge eine Storage-Policy hinzu, mit der jede Person nur die Dateien lesen kann, die sie sehen soll. Lade dann die Seite mit dem kaputten Bild neu.
Was deine Buckets Fremden gerade zeigen
Zwei Ansichten im Dashboard sagen dir, was du eingestellt hast, und eine Prüfung von außen sagt dir, was ein Fremder bekommt.
Storage → Buckets zeigt, welche Buckets öffentlich sind. Frag dich bei jedem
öffentlichen, ob jede Datei darin etwas ist, das du einem Fremden zeigen
würdest. Storage → Policies zeigt die Regeln. Eine select-Regel, deren
einzige Bedingung der Bucket-Name ist, lässt jeden diesen Bucket lesen, seine
Dateiliste eingeschlossen.
Unser kostenloser Scan fragt dein Live-Projekt nach der Dateiliste jedes Buckets, nur mit dem Schlüssel, der ohnehin im Code deiner App steht, so wie es ein Fremder tun würde, und sagt dir, welche Buckets mit Namen geantwortet haben. Er liest Namen und lädt nie eine Datei herunter. Er dauert etwa 20 Sekunden und braucht kein Konto: scanne deine App.
Wie deine Dateien dort bleiben, wo du sie abgelegt hast
Nach der heutigen Korrektur können sich noch zwei Dinge bewegen: Jemand legt eine Einstellung um, während er einem anderen Fehler nachgeht, und eine Datei, die jemand gebraucht hat, wird gelöscht.
Reeve Monitor prüft weiter von außen:
- die vollständige Sicherheitsprüfung, erneut nach Zeitplan, die Prüfung der Bucket-Auflistung eingeschlossen
- ob deine App erreichbar ist
- eine Nachricht, wenn sich ein Ergebnis ändert, damit ein Bucket, der über Nacht aufgegangen ist, nicht wartet, bis du hinschaust
- ein monatlicher Bericht in einfacher Sprache über das, was er gesehen hat
Reeve Care hält eine Kopie von dem, was drinliegt:
- eine verschlüsselte Kopie deiner Supabase-Datenbank nach Zeitplan, auf Reeves eigenem Speicher in der EU, außerhalb deines Supabase-Kontos
- jede Kopie geprüft, bevor sie zählt, durch Zählen der Zeilen in jeder Tabelle
- auch deine hochgeladenen Dateien, sobald du einen Storage-Zugang verbindest
- eine Wiederherstellung per Klick, mit einer Sicherheitskopie des aktuellen Stands vorab
- alles, was Monitor tut
Was heute zu tun ist
Was zu tun ist
- Öffne den gescheiterten Link in einem eigenen Tab. Enthält die Adresse
/storage/v1/object/public/und ist der Bucket privat, ist es die erste Ursache. - Kopier den Namen des Buckets aus Storage → Buckets und vergleich ihn, Großbuchstaben eingeschlossen, mit dem Namen, den deine App benutzt.
- Vergleich die Projektreferenz in der Supabase-Adresse deiner App mit der in der Adresse deines Dashboards.
- Lass einen Bucket privat, außer jede Datei darin ist für jeden gedacht, der ihre Adresse hat, und liefere private Dateien über signierte Links aus.
- Lies jede
select-Regel aufstorage.objects. Eine, die nur den Bucket nennt, gibt auch die Dateiliste heraus.
Fang mit der Anfrage an, die gescheitert ist, denn die Tür, durch die sie kam, sagt dir, welche der drei Ursachen du prüfen musst. Die 10-Minuten-Sicherheitscheckliste deckt ab, was eine frisch gestartete App sonst gern offen lässt, und was ein öffentlicher Bucket preisgibt ist die nächste Lektüre, falls sich einer deiner Buckets als öffentlich herausgestellt hat.
FAQ
Warum sagt Supabase, mein Bucket wird nicht gefunden, obwohl ich ihn sehe?
Weil Storage je nach Anfrage auf unterschiedliche Weise nach einem Bucket sucht. Eine öffentliche Dateiadresse, wie getPublicUrl sie baut, wird nur unter öffentlichen Buckets gesucht, also gilt ein privater Bucket, den du im Dashboard siehst, dort als nicht gefunden. Kam der Fehler dagegen von einem Upload, dann passt der Name in deinem Code zu keinem Bucket in dem Projekt, mit dem deine App verbunden ist.
Unterscheidet Supabase bei Bucket-Namen zwischen Groß- und Kleinschreibung?
Ja. Storage vergleicht den Namen Zeichen für Zeichen, also sind Avatars und avatars zwei verschiedene Buckets, und avatar und avatars ebenso. Kopier den Namen aus Storage → Buckets in deinem Dashboard und vergleich ihn mit dem Namen, den deine App benutzt.
Soll ich meinen Bucket öffentlich machen, um "Bucket not found" zu beheben?
Nur wenn jede Datei darin für jeden gedacht ist, der ihre Adresse hat, etwa Profilbilder oder Produktfotos. Öffentlich heißt, dass jeder mit der Adresse einer Datei diese Datei ohne Anmeldung öffnen kann. Den Fehler behebt das nur, wenn ein öffentlicher Link für einen privaten Bucket gebaut wurde; ein falscher Name oder ein falsches Projekt bleibt so oder so kaputt. Für Dateien, die einer Person gehören, lass den Bucket privat und nimm einen signierten Link.
Wie zeige ich eine Datei aus einem privaten Bucket an?
Mit einem signierten Link. createSignedUrl baut eine Adresse, die für eine Anzahl Sekunden funktioniert, die du festlegst, und danach nicht mehr, und sie tritt überall an die Stelle von getPublicUrl, wo eine Seite die Datei zeigt. Wer den Link anfordert, muss die Datei lesen dürfen, also braucht der Bucket eine select-Regel auf storage.objects, die festlegt, wer was lesen darf.
Warum sagt der Fehler 404, wenn die Anfrage mit 400 gescheitert ist?
Supabase Storage schickt diesen Fehler mit dem HTTP-Status 400 und legt seinen eigenen Status, 404, als statusCode in den Body. In supabase-js kommt das als error.status 400 und error.statusCode "404" an, und deshalb lässt Code, der auf eine 404 wartet, diesen Fehler einfach durch.