Anleitung

Fehler von Kartenkachel-APIs erklärt

Was 401, 403, 404 und 429 bei Kartenkacheln bedeuten, warum OpenStreetMap-Kacheln «Access blocked» zeigen, warum eine Karte leer oder grau bleibt, und die Meldungen von MapLibre, Leaflet und Google Maps, die dazugehören. Jeweils mit der üblichen Ursache und der Lösung.

Sie sehenMeistensLösung
«Access blocked» oder «Referer is required» auf OpenStreetMap-KachelnDie Anfrage verletzt die Nutzungsrichtlinie von tile.openstreetmap.org.Einen Referer senden, Kacheln zwischenspeichern, oder einen anderen Kacheldienst verwenden.
401 UnauthorizedSchlüssel oder Token fehlt, ist falsch oder gelöscht.Den Schlüssel in der URL prüfen, die der Browser anfragt.
403 Forbidden, «Invalid key»Der Schlüssel ist für diese Website oder diesen Dienst nicht erlaubt.Die Website zu den erlaubten Origins des Schlüssels hinzufügen.
429 Too Many RequestsDas Monatskontingent oder ein Limit pro Minute ist aufgebraucht.Auf Retry-After warten, Kacheln zwischenspeichern, oder den Tarif wechseln.
404 Not Found bei KachelnEine Zoomstufe über der höchsten des Kachelsatzes, oder eine falsche URL-Vorlage.maxzoom an der Quelle setzen; {z}/{x}/{y} prüfen.
«Unable to parse the tile», «Unimplemented type: 3»Gzip-komprimierte Kacheln ohne Content-Encoding: gzip.Den Header senden, oder auf dem Server entpacken.
«has been blocked by CORS policy»Kein Header Access-Control-Allow-Origin, oft bei einer Fehlerantwort.Den Statuscode im Netzwerk-Tab ansehen.
Image «…» could not be loadedDer Stil nennt ein Symbol, das sein Sprite nicht hat.Das Sprite verwenden, für das der Stil gemacht ist, oder das Bild ergänzen.
«Style is not done loading»Layer hinzugefügt, bevor der Stil geladen ist.Sie in map.on("load") hinzufügen.
«You are using the same source for a hillshade layer and for 3D terrain»Eine raster-dem-Quelle für beides.Zwei Quellen mit derselben URL verwenden.
«Expected value to be of type number, but found null instead.»Ein Ausdruck im Stil liest ein Feld, das manchen Features fehlt.Mit coalesce einen Standardwert geben.
«Google Maps wurde auf dieser Seite nicht richtig geladen»Ein Problem mit API-Schlüssel, Abrechnung oder Referer in Google Cloud.Den Namen des Fehlers in der Konsole lesen.
Leaflet: graue Karte, Kacheln durcheinander, «Map container is already initialized»Fehlendes CSS, ein verstecktes Element, oder ein zweites L.map().leaflet.css laden, invalidateSize() aufrufen, vorher remove() aufrufen.
Eine leere Karte ohne FehlerDas Kartenelement hat keine Höhe, oder Stil und Kacheln passen nicht zusammen.Dem Element eine Höhe geben; den Stil für die Kacheln verwenden.

OpenStreetMap-Kacheln: «Access blocked»

Die Kachelserver unter tile.openstreetmap.org werden von Freiwilligen für die Website von OpenStreetMap und ihre Editoren betrieben. Andere Websites dürfen sie im Rahmen der Nutzungsrichtlinie für Kacheln verwenden. Verletzt eine Anfrage sie, antwortet der Server mit HTTP 403 und einem Bild der Meldung statt der Karte; der Fehler erscheint also auf der Karte selbst. Das Wiki von OpenStreetMap nennt die Gründe auf seiner Seite Blocked tiles:

  • «Referer is required»: Der Browser hat keinen Header Referer gesendet. Das passiert, wenn die Seite Referrer-Policy: no-referrer setzt, wenn ein Datenschutz-Add-on oder ein Antivirenprogramm den Header entfernt, und wenn die Karte aus einer lokalen Datei läuft. Setzen Sie die Policy der Seite auf strict-origin-when-cross-origin, den Standard der Browser, oder auf origin.
  • Kein gültiger User-Agent: Apps ausserhalb eines Browsers müssen einen User-Agent senden, der die App nennt.
  • Massen-Download, kein Caching oder zu viele Anfragen: Gebiete für die Offline-Nutzung vorausladen, Cache-Control: no-cache senden, oder Kacheln schneller laden, als eine Person eine Karte verschiebt.
  • «Blocked for not attributing»: Die Karte zeigt die Quellenangabe © OpenStreetMap nicht.

Eine Sperre endet von selbst, sobald die App korrigiert ist. Für eine App oder Website mit regelmässigem Verkehr erwartet die Richtlinie, dass Sie einen eigenen oder einen kommerziellen Kacheldienst verwenden; die OpenStreetMap-Daten bleiben so oder so frei.

Die Einstellungen von Helmet, Django, nginx, Apache und Caddy und Code für Leaflet, OpenLayers und MapLibre stehen in der Anleitung OpenStreetMap-Kacheln: «Access blocked».

401 Unauthorized

Der Kacheldienst hat den Schlüssel oder das Token nicht angenommen: Es fehlt, ist vertippt, gelöscht, oder es ist ein altes nach einem Wechsel des Schlüssels.

  • Öffnen Sie den Netzwerk-Tab des Browsers, und sehen Sie sich die URL der Kachel oder des Stils an, die der Browser angefragt hat. Ein Platzhalter wie YOUR_KEY oder get_your_own_key, der in einer Stil-URL stehen geblieben ist, oder eine Umgebungsvariable, die beim Build leer war, ist die häufigste Ursache.
  • Mapbox antwortet ohne Token mit {"message":"Not Authorized - No Token"}, und mit 401 bei einem gelöschten Token oder beim alten öffentlichen Standard-Token, nachdem es erneuert wurde.
  • Stadia Maps antwortet mit 401, wenn die Website nicht für die Domain-Authentifizierung registriert ist und kein API-Schlüssel mitkommt. Auf localhost braucht es keines von beiden, mit einem tiefen Limit.
  • Das Stil-JSON enthält den Schlüssel oft in mehreren URLs (Kacheln, Sprite, Glyphen). Wenn Sie einen Stil kopiert haben, ersetzen Sie den Schlüssel in allen.

403 Forbidden und «Invalid key»

Der Schlüssel ist gültig, aber für diese Anfrage nicht erlaubt. Meistens ist er auf bestimmte Websites beschränkt, und die Seite, die die Karte lädt, gehört nicht dazu.

  • Fügen Sie jeden Host, auf dem die Karte läuft, zu den erlaubten Websites des Schlüssels hinzu, mit und ohne www., dazu Test-Hosts und localhost für die Entwicklung. Mapbox nennt das URL restrictions, MapTiler «Allowed HTTP origins».
  • Eine Anfrage ohne Origin oder Referer scheitert, sobald ein Schlüssel irgendeine Beschränkung hat. Deshalb funktioniert ein beschränkter Schlüssel im Browser und scheitert in curl, Postman, QGIS oder einer Handy-App. Verwenden Sie dort einen eigenen Schlüssel ohne Beschränkung auf Websites, und halten Sie ihn aus Webseiten heraus.
  • MapTiler zeigt «Invalid key» für einen Schlüssel, den es nicht gibt, und für ein nicht erlaubtes Origin.
  • Mapbox antwortet auch mit 403, wenn dem Token ein Scope fehlt, etwa STYLES:READ zum Laden eines Stils.
  • Eine Seite mit Referrer-Policy: no-referrer sendet gar keinen Referer, und jede Prüfung der Website scheitert.

429 Too Many Requests

Das Konto hat sein Monatskontingent an Kacheln verbraucht oder in kurzer Zeit zu viele geschickt. Die meisten kostenlosen Tarife liefern keine Kacheln mehr bis zum nächsten Monat, sobald das Kontingent aufgebraucht ist.

  • Warten Sie so lange, wie der Header Retry-After sagt. MapLibre fordert die Kacheln beim nächsten Verschieben oder Zoomen von selbst neu an.
  • Schätzen Sie die Kacheln, die Sie brauchen: Eine Karte über den ganzen Bildschirm lädt beim Öffnen etwa 15 bis 30 Kacheln, und mit jedem Verschieben und Zoomen mehr. Eine Karte mit 3D-Gelände lädt zusätzlich Geländekacheln.
  • Lassen Sie den Cache des Browsers eingeschaltet. Hängen Sie keine Parameter gegen den Cache an Kachel-URLs, und laden Sie keine ganzen Gebiete voraus.
  • Eine Karte in einer Seite, die sich alle paar Sekunden neu lädt, etwa ein Dashboard auf einem Bildschirm an der Wand, verbraucht ein Kontingent schnell. Laden Sie die Daten neu, und behalten Sie die Karte.

404 Not Found bei Kacheln

  • Die Karte fragt nach einer Zoomstufe über der höchsten des Kachelsatzes. Setzen Sie maxzoom an der Quelle auf die höchste Zoomstufe der Kacheln; MapLibre vergrössert diese dann für nähere Ansichten. Zeigt "url" auf eine TileJSON-Datei, liest MapLibre den Zoombereich daraus.
  • Die URL-Vorlage ist falsch: {z}/{x}/{y} in anderer Reihenfolge, .pbf statt .mvt, oder ein fehlender Teil des Pfads. Öffnen Sie eine Kachel-URL mit echten Zahlen im Browser.
  • Kacheln im TMS-Schema zählen die Zeilen von Süden her. Ergänzen Sie "scheme": "tms" an der Quelle, sonst erscheinen Kacheln auf der falschen Halbkugel, und viele fehlen.
  • Manche Server antworten bei Kacheln ohne Daten, etwa auf offenem Meer, mit 404 oder 204. Ein 204 ist normal, und MapLibre zeigt dort nichts.

«Unable to parse the tile» und «Unimplemented type: 3»

Aktuelle Versionen von MapLibre GL JS melden:

Unable to parse the tile at https://…/14/8580/5737.pbf, please make sure the data is not gzipped and that you have configured the relevant header in the server

Ältere Versionen von MapLibre und Mapbox GL JS sagen Unimplemented type: 3, oder eine andere Zahl. Der Decoder hat Bytes erhalten, die keine Vektorkachel sind. Fast immer sind das gzip-komprimierte Kacheln aus einer MBTiles- oder PMTiles-Datei, die ohne den Header Content-Encoding: gzip ausgeliefert werden, sodass der Browser sie nicht entpackt. Seltener ist es eine Fehlerseite in HTML oder JSON, oder eine PNG-Rasterkachel, die einer Vektorquelle übergeben wird.

curl -sI 'https://tiles.example.com/14/8580/5737.pbf' | grep -i -e content-type -e content-encoding
curl -s 'https://tiles.example.com/14/8580/5737.pbf' | head -c 2 | xxd   # 1f8b heisst gzip

Senden Sie Content-Encoding: gzip mit gzip-Kacheln (in nginx add_header Content-Encoding gzip; in der Location der Kacheln), oder entpacken Sie sie auf dem Server. Wie Sie die Ursachen unterscheiden, und getestete Einstellungen für nginx, Apache, Caddy, S3 und PMTiles: MapLibre: «Unable to parse the tile».

«has been blocked by CORS policy»

Access to fetch at 'https://tiles.example.com/…' from origin 'https://www.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

MapLibre lädt Stile, Kacheln, Schriften und Symbole mit fetch; jede dieser Antworten braucht also einen Header Access-Control-Allow-Origin. Kacheldienste senden ihn, manche aber nur bei erfolgreichen Antworten. Dann erscheint ein 401, 403 oder 429 in der Konsole als CORS-Fehler und verdeckt seine Ursache. Sehen Sie sich den Statuscode der Anfrage im Netzwerk-Tab an, und lesen Sie dann den Abschnitt zu diesem Code oben. Mit einem eigenen Kachelserver ergänzen Sie den Header bei jeder Antwort, auch bei Fehlern.

Image «…» could not be loaded

Image "cafe" could not be loaded. Please make sure you have added the image before it is needed with map.addImage(), resolved it with map.setMissingStyleImageResolver(), or included it in a "sprite" property in your style.

Ein Layer des Stils verwendet ein Symbol, das sein Sprite nicht enthält. Es ist nur eine Warnung, und die Karte funktioniert ohne dieses Symbol. Sie erscheint, wenn ein Stil mit einem anderen Sprite als seinem eigenen verwendet wird, oder wenn Sie einen Layer mit einem eigenen icon-image hinzufügen. Laden Sie Ihr Symbol mit map.loadImage() und map.addImage(), bevor der Layer es braucht, oder ergänzen Sie den Stil um ein zweites Sprite (MapLibre nimmt eine Liste von Sprites).

«Style is not done loading»

Dieser Fehler kommt, wenn map.addSource() oder map.addLayer() läuft, bevor der Stil geladen ist. Fügen Sie Ihre Quellen und Layer in map.on("load", …) hinzu. Nach map.setStyle() sind die alten Layer weg: Fügen Sie Ihre in map.on("style.load", …) erneut hinzu.

«You are using the same source for a hillshade layer and for 3D terrain»

You are using the same source for a hillshade layer and for 3D terrain. Please consider using two separate sources to improve rendering quality.

Erstellen Sie zwei Quellen vom Typ raster-dem mit derselben URL, eine für den hillshade-Layer und eine für terrain. Der Browser holt jede Kachel einmal und liefert die zweite Kopie aus seinem Cache.

«Expected value to be of type number, but found null instead.»

Ein Ausdruck im Stil liest ein Feld, das manchen Features fehlt, zum Beispiel ["get", "height"] bei Gebäuden ohne Höhe. Geben Sie einen Standardwert, ["coalesce", ["get", "height"], 10], oder beschränken Sie den Layer mit einem Filter auf Features, die es haben: ["has", "height"]. Viele solche Warnungen auf einmal bedeuten oft, dass der Stil für ein anderes Kachelschema gemacht ist (siehe leere Karte).

Google Maps: «Google Maps wurde auf dieser Seite nicht richtig geladen»

Die Karte wird dunkel, mit «Nur für Entwicklungszwecke» darüber (englisch: «This page can't load Google Maps correctly», «For development purposes only»). Die Konsole des Browsers nennt den Grund als einen dieser Fehler.

  • InvalidKeyMapError oder MissingKeyMapError: Der Parameter key ist falsch oder fehlt.
  • RefererNotAllowedMapError: Die Website gehört nicht zu den HTTP-Referrern, die für den Schlüssel erlaubt sind.
  • ApiNotActivatedMapError: Die Maps JavaScript API ist im Google-Cloud-Projekt des Schlüssels nicht aktiviert.
  • BillingNotEnabledMapError: Das Projekt hat kein Rechnungskonto. Google verlangt eines auch innerhalb des kostenlosen Monatsbetrags.
  • ExpiredKeyMapError: Der Schlüssel wurde gelöscht oder ersetzt.

Alle lassen sich in der Google Cloud Console unter APIs & Dienste beheben. Jeder Code mit seiner Lösung, Beschränkungen auf Websites, die funktionieren, und was eine Karte mit und ohne Google kostet: Google Maps: «Google Maps wurde auf dieser Seite nicht richtig geladen».

Leaflet: graue Karte, Kacheln durcheinander, «Map container is already initialized»

  • Die Kacheln erscheinen als Spalte von Bildern, mit Lücken oder verschoben: leaflet.css ist nicht geladen. Laden Sie es, bevor die Karte erstellt wird.
  • Die Karte bleibt grau, bis das Fenster seine Grösse ändert: Sie wurde in einem versteckten Element erstellt, etwa in einem Tab oder einem Dialog. Rufen Sie map.invalidateSize() auf, wenn das Element sichtbar wird.
  • Map container is already initialized.: L.map() lief zweimal auf demselben Element, oft nach einem erneuten Rendern in React oder Vue oder einem Hot Reload. Rufen Sie map.remove() auf, bevor Sie die Karte neu erstellen, oder erstellen Sie sie einmal.
  • Map container not found.: Das Skript läuft, bevor das Element existiert. Setzen Sie das Skript dahinter, oder warten Sie auf DOMContentLoaded.
  • Leaflet zeigt Rasterkacheln (PNG). Für Vektorkacheln braucht es ein Plugin wie maplibre-gl-leaflet.

Eine leere Karte ohne Fehler

  • Das Kartenelement hat keine Höhe. Ein div ohne Inhalt ist 0 Pixel hoch; die Karte ist also da, aber nicht zu sehen. Geben Sie ihm eine: #map { height: 480px; }. Das ist die häufigste Ursache überhaupt.
  • Der Stil ist für ein anderes Kachelschema gemacht. OpenMapTiles, Shortbread, Protomaps und Mapbox Streets verwenden verschiedene Layernamen und Felder; ein Stil für das eine zeigt auf den anderen nur seinen Hintergrund. Verwenden Sie den Stil, der zu den Kacheln gehört.
  • MapLibre braucht WebGL. Auf Remote-Desktops, in manchen virtuellen Maschinen und in Browsern mit abgeschalteter Hardwarebeschleunigung kann es fehlen; die Konsole meldet dann einen WebGL-Fehler.
  • Die Karte ist auf [Breite, Länge] statt auf [Länge, Breite] zentriert. MapLibre nimmt zuerst die Länge, Leaflet die Breite.

Eine Kachel von Hand prüfen

Fragen Sie eine Kachel mit den Headern an, die ein Browser sendet, und sehen Sie sich Status, Typ und die ersten Bytes an:

curl -s -o tile.mvt -w '%{http_code} %{content_type}\n' \
  -H 'Accept-Encoding: gzip' -H 'Referer: https://www.example.com/' \
  'https://api.overpass.ch/v1/IHR_SCHLÜSSEL/maps/vector/14/8580/5737.mvt'
head -c 300 tile.mvt | xxd | head   # ein Fehler ist lesbarer Text, eine Kachel ist binär

Auf overpass.ch ist ein Fehler immer JSON mit einem Code und einer Meldung, und er hat die CORS-Header; der Browser zeigt ihn also, wie er ist:

{"error":"forbidden_referer","message":"…"}
StatusCodeBedeutung auf overpass.ch
401unauthorizedDer Schlüssel in der URL fehlt oder ist unbekannt.
403forbidden_refererDie Website gehört nicht zu den erlaubten Referern des Schlüssels.
403key_scopeEin Schlüssel «Nur Karten» wurde für Overpass oder Höhen verwendet.
404not_foundEine Zoomstufe über dem Kachelsatz; Karten vergrössern stattdessen die höchste Zoomstufe.
204–Eine Kachel ohne Daten, etwa offenes Meer. Kostenlos.
429rate_limited, quota_exceededDas Limit pro Minute eines kostenlosen Tarifs, oder die Kacheln des Monats; siehe Retry-After.
503server_busy, maps_unavailableNach den Sekunden in Retry-After noch einmal versuchen.

Alle Codes stehen in der Dokumentation.

Zu einem anderen Kacheldienst wechseln

Mit MapLibre GL JS ist ein Kacheldienst eine einzige Stil-URL. Für den Wechsel ersetzen Sie die URL, behalten Ihre eigenen Quellen und Layer und fügen sie nach setStyle() wieder hinzu. Die Layernamen ändern sich mit dem Kachelschema; Ihre Layer, die sich auf Layer des alten Stils beziehen (zum Beispiel mit beforeId), brauchen also neue Namen.

Kartenkacheln von overpass.ch

Vektorkacheln der ganzen Welt für MapLibre in neun Stilen, darunter Outdoor mit Wanderwegen nach Skala und Marine mit Tiefen und Seezeichen, Beschriftung in 41 Sprachen und 3D-Gelände. 100'000 Kacheln im Monat sind kostenlos, Schlüssel lassen sich auf Ihre Websites beschränken, und Fehler kommen als JSON mit Retry-After.