Praxisanleitung

„Failed to fetch“ beim Absenden des Kontaktformulars: So finden Sie die echte Ursache

Chrome sagt „Failed to fetch“, Firefox „NetworkError when attempting to fetch resource“, Safari „Load failed“, egal was schiefging. Wir haben acht Ursachen in allen drei Engines nachgestellt und jeder die Konsolenzeile zugeordnet, die sie verrät.

Die kurze Antwort. „Failed to fetch“ sagt nur, dass die Anfrage nicht abgeschlossen wurde, und der Text ist bei jeder Ursache derselbe. Öffnen Sie die Browser-Konsole und lesen Sie die Zeile direkt darüber. „blocked by CORS policy“: Der Endpunkt erlaubt Ihre Website nicht. ERR_NAME_NOT_RESOLVED: Die URL ist falsch, oft https://undefined wegen einer fehlenden Umgebungsvariable. ERR_CONNECTION_REFUSED: Dort läuft nichts. „Mixed Content“: ein http-Endpunkt auf einer https-Seite. „violates the following Content Security Policy directive“: Ihre CSP blockiert ihn. Prüfen Sie außerdem, ob der Submit-Handler event.preventDefault() aufruft.

Formgong

Kontaktformular „Failed to fetch“: Ursachen und Lösungen
„Failed to fetch“ beim Absenden des Kontaktformulars: So finden Sie die echte Ursache

Derselbe Fehler für jede Ursache

Kann fetch eine Anfrage nicht abschließen, wirft der Browser einen TypeError mit einer festen Meldung. In unseren Tests (11.10.2026) erzeugte jeder Fehlerfall pro Browser genau denselben Text:

  • Chrome, Edge und andere Chromium-Browser: TypeError: Failed to fetch
  • Firefox: TypeError: NetworkError when attempting to fetch resource.
  • Safari: TypeError: Load failed

Browser verbergen den Grund absichtlich vor Ihrem JavaScript, damit eine Seite keine fremden Websites ausspähen kann. Der Grund steht separat in der Konsole, eine Zeile über dem Fehler. Öffnen Sie in Chrome die DevTools (F12), wechseln Sie zum Tab „Console“, senden Sie das Formular noch einmal ab und lesen Sie die rote Zeile vor „Failed to fetch“. Im Tab „Network“ erscheint dieselbe Anfrage rot, mit ihrem Status.

Konsolenzeile und Ursache zuordnen

Das sind die Chrome-Konsolenzeilen aus unserem Nachbau. Firefox und Safari formulieren anders; das steht weiter unten.

„Failed to fetch“: Konsolenzeile und Ursache
Konsolenzeile (Chrome)UrsacheHat der Server die Nachricht bekommen?
“has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.”Der Endpunkt erlaubt Ihre Website nicht, oder er ist abgestürzt und seine Fehlerseite hat keinen CORS-HeaderOft ja
“Response to preflight request doesn't pass access control check”Der Endpunkt beantwortet den OPTIONS-Preflight nicht, den ein JSON-Body auslöstNein
net::ERR_NAME_NOT_RESOLVEDDen Host gibt es nicht: ein Tippfehler oder https://undefined/… wegen einer fehlenden UmgebungsvariableNein
net::ERR_CONNECTION_REFUSEDUnter der Adresse lauscht nichts, meist ein lokaler Dev-Server, der nicht läuftNein
net::ERR_CERT_AUTHORITY_INVALID und ähnlicheDas Zertifikat des Endpunkts ist ungültig oder abgelaufenNein
“Mixed Content: The page at 'https://…' was loaded over HTTPS, but requested an insecure resource 'http://…'”Ein http://-Endpunkt auf einer https://-WebsiteNein
“violates the following Content Security Policy directive: "connect-src …"”Die CSP Ihrer Seite führt den Endpunkt nicht aufNein
net::ERR_BLOCKED_BY_CLIENTEin Werbeblocker oder eine Datenschutz-Erweiterung (von Nutzern berichtet, von uns nicht nachgestellt)Nein

„Blocked by CORS policy“: Die Nachricht kann trotzdem angekommen sein

CORS ist die Regel, mit der ein Server festlegt, welche Websites seine Antworten lesen dürfen. Schickt Ihr Formular an eine API auf einer anderen Domain, muss die API mit Access-Control-Allow-Origin antworten und darin Ihre Website nennen (oder *). Fehlt das, verwirft der Browser die Antwort, und Ihr Code bekommt „Failed to fetch“.

In unserem Test hat der Server bei einem FormData-Body den POST empfangen und gespeichert, mit 200 geantwortet, und erst danach hat der Browser die Antwort blockiert. Der Besucher sah einen Fehler zu einer Nachricht, die längst angekommen war, und wer es noch einmal versucht, sendet sie doppelt. Mit einem JSON-Body ist es anders: Der Browser schickt zuerst einen OPTIONS-„Preflight“, und scheitert der, geht der POST gar nicht erst raus.

Ein Absturz auf dem Server sieht genauso aus. In unserem Test lieferte ein Endpunkt, der den Preflight korrekt beantwortete, aber einen 500er ohne CORS-Header zurückgab, dieselbe Zeile „No 'Access-Control-Allow-Origin' header“. Der eigentliche Fehler versteckte sich also hinter einer CORS-Meldung. Sehen Sie ins Server-Log, bevor Sie die CORS-Einstellungen anfassen. Bei Supabase ist es genauso getrennt: Ein Absturz kommt als „Failed to send a request to the Edge Function“ zurück, und eine Funktion, die mit 4xx oder 5xx geantwortet hat, liefert „Edge Function returned a non-2xx status code“. Die eigentliche Meldung steht dann in error.context.

Die Lösung gehört auf den Server: OPTIONS beantworten und den Header in jede Antwort schreiben, auch in Fehlerantworten. mode: "no-cors" löst nichts: Die Antwort wird damit unlesbar, und Ihr Formular kann Erfolg nicht mehr von einem Fehler unterscheiden.

Server (beliebige Laufzeit)
// Answer the preflight, and add the header to every reply, errors included.
const cors = {
  "Access-Control-Allow-Origin": "https://yourdomain.com",
  "Access-Control-Allow-Methods": "POST, OPTIONS",
  "Access-Control-Allow-Headers": "Content-Type",
};
if (request.method === "OPTIONS") return new Response(null, { status: 204, headers: cors });

Eine falsche oder leere URL

KI-Baukästen und Frameworks lesen den Endpunkt oft aus einer Umgebungsvariable. Ist die Variable auf Ihrem Rechner gesetzt, beim Hoster aber nicht, wird aus der URL das Wort undefined. Bei einer absoluten URL, https://undefined/api/submit, findet der Browser den Host nicht, und Sie bekommen ERR_NAME_NOT_RESOLVED und „Failed to fetch“. Bei einer relativen, undefined/api/submit, gibt es überhaupt keinen Fehler: In unserem Test bekam fetch stillschweigend einen 404 von Ihrer eigenen Website. Suchen Sie im gebauten JavaScript nach dem wörtlichen Text undefined/ und tragen Sie die Variable in den Einstellungen Ihres Hosters ein.

ERR_CONNECTION_REFUSED ist die lokale Variante desselben Problems: Das Formular zeigt auf localhost:3000 oder localhost:8787, und dort läuft nichts, oder die Live-Seite zeigt noch auf Ihren Laptop.

Mixed Content und CSP

Eine per https ausgelieferte Seite darf keine Anfragen an eine http://-Adresse schicken. Alle drei Browser haben das in unserem Test für einen öffentlichen Host blockiert, die Anfrage ging nie raus. Stellen Sie den Endpunkt auf https:// um. Chrome ließ eine https-Seite allerdings an eine private Netzwerkadresse wie http://192.168.1.130 senden, Firefox und Safari blockierten das. Ein Formular, das in Chrome im Büronetz funktioniert, kann anderswo also trotzdem scheitern.

Setzt Ihre Website eine Content Security Policy, muss deren connect-src den Origin des Endpunkts enthalten. Sonst verweigert jeder Browser die Anfrage, bevor sie die Seite verlässt.

So formulieren es Firefox und Safari

Firefox schreibt „Cross-Origin Request Blocked … (Reason: CORS request did not succeed). Status code: (null).“ bei einem fehlenden Host, einer abgelehnten Verbindung und einem fehlerhaften Zertifikat, obwohl nichts davon mit CORS zu tun hat. Sehen Sie diese Zeile, prüfen Sie zuerst die URL und den Server. Ein echtes CORS-Problem lautet in Firefox „(Reason: CORS header 'Access-Control-Allow-Origin' missing)“ und nennt einen Statuscode.

Safari schreibt „Origin … is not allowed by Access-Control-Allow-Origin“ bei CORS, „A server with the specified hostname could not be found.“ bei einem falschen Host, „Could not connect to the server.“, wenn nichts lauscht, und „The certificate for this server is invalid.“ bei Zertifikaten.

Das Formular verlässt die Seite, bevor fetch fertig ist

Ruft der Submit-Handler kein event.preventDefault() auf, startet der Browser das normale Absenden des Formulars und verlässt die Seite, während Ihr fetch noch läuft. In unserem Test verhielten sich die Browser unterschiedlich: In Firefox und Safari wurde die Anfrage jedes Mal abgebrochen, und der Server bekam die Nachricht nie (Safari zeigte den Fehler zusätzlich in einem Dialog). Chrome ließ sie manchmal durch. Rufen Sie preventDefault() in der ersten Zeile des Handlers auf und zeigen Sie Erfolg nur, wenn die Antwort ihn meldet.

In unserem Test von 105 KI-gebauten Websites sagten 27 Formulare den Besuchern, ihre Nachricht sei gesendet, obwohl sie es nicht war (die Studie).

JavaScript
form.addEventListener("submit", async (event) => {
  event.preventDefault(); // without this the browser leaves the page mid-request
  try {
    const response = await fetch(form.action, { method: "POST", body: new FormData(form) });
    const data = await response.json();
    if (!response.ok || data.success !== true) throw new Error(data.message || "Not sent");
    showSuccess();
  } catch (error) {
    // "Failed to fetch" lands here. The console line above it says why.
    showError("Your message was not sent. Please try again or email us.");
  }
});

Werbeblocker

Datenschutz-Erweiterungen blockieren Anfragen, deren URL auf ihre Filterlisten passt, besonders Wörter wie track oder analytics. Chrome zeigt dann ERR_BLOCKED_BY_CLIENT. Eine echte Erweiterung konnten wir in einem automatisierten Browser nicht nachstellen; dieser Fall stammt aus Nutzerberichten und von MDN. Zum Prüfen senden Sie das Formular in einem privaten Fenster ohne Erweiterungen ab. Klappt es dort, benennen Sie den Pfad des Endpunkts um oder bitten Sie Besucher, Ihre Website freizugeben.

Ein Formular-Backend, das jede Antwort mit CORS-Header schickt

Der Endpunkt von Formgong, https://formgong.com/submit, sendet Access-Control-Allow-Origin: * bei jeder Antwort, auch bei Fehlern. Ein falscher Schlüssel kommt in Ihrem Code also als lesbarer 404 mit "success": false an statt als „Failed to fetch“. Ein normales HTML-Formular braucht gar kein JavaScript. Siehe die HTML-Anleitung oder die Anleitung für Ihren Baukasten.

Alles in einem Konto. Feedback erwünscht

Mit einem Formgong-Konto bekommen Sie neben dem Kontaktformular, das an E-Mail und Telegram sendet, auch kostenlose Website-Vorlagen (auf Englisch), in denen das Formular schon angeschlossen ist, einen KI-Hilfe-Chat, der Fragen Ihrer Besucher aus Ihren eigenen Seiten beantwortet, und Kundenbewertungen zum Sammeln und Anzeigen. Anfragen landen in einem Posteingang. Jedes dieser Produkte hat einen kostenlosen Tarif.

Fehlt Ihnen auf dieser Seite etwas, oder ist etwas unklar? Schreiben Sie uns an support@formgong.com. Wir lesen jede Nachricht und verbessern die Seite danach.

Häufig gestellte Fragen

Was bedeutet TypeError: Failed to fetch?

Der Browser konnte die Anfrage nicht abschließen oder durfte die Antwort nicht lesen. Der Text ist bei jeder Ursache derselbe; die Konsolenzeile direkt darüber nennt den eigentlichen Grund.

Ist „Failed to fetch“ immer ein CORS-Fehler?

Nein. Er erscheint auch bei einer falschen oder undefined-URL, einem Server, der nicht läuft, einem ungültigen Zertifikat, einem http-Endpunkt auf einer https-Seite, einer Blockade durch die Content Security Policy, einem Werbeblocker und einer Seite, die mitten in der Anfrage weiternavigiert.

Mein Formular zeigt Failed to fetch, aber die E-Mail ist angekommen. Wie kann das sein?

Bei einem FormData-Body und einem Server ohne CORS-Header speichert der Server die Nachricht, und der Browser blockiert nur die Antwort. Setzen Sie Access-Control-Allow-Origin auf dem Server, damit das Formular die Antwort lesen kann.

Wie heißt dieser Fehler in Firefox und Safari?

Firefox: „NetworkError when attempting to fetch resource.“ Safari: „Load failed“. Beide haben dieselben Ursachen wie „Failed to fetch“ in Chrome.

Quellen und Dokumentation

Offizielle Quellen zu dieser Anleitung: MDN: CORS-Fehler, MDN: Reason: CORS request did not succeed, MDN: Ausnahmen von fetch(), MDN: Mixed Content, Chrome: Local Network Access. HTML-Kontaktformular, wo die Daten gespeichert werden.

Bewerten Sie diesen Leitfaden

Ihre Bewertung

Wir lesen jede Bewertung. Ein Kommentar erscheint hier erst nach unserer Freigabe.

← Zurück zum Blog