JSON-Fehler verstehen: ungültiges JSON finden und beheben
Komma am Ende, einfache Anführungszeichen, Kommentare, eine unsichtbare BOM: Wir haben 26 fehlerhafte JSON-Schnipsel an Chrome, Python und PHP verfüttert und notiert, was jeder meldet. So lesen Sie die Meldung und beheben die eigentliche Ursache.
JSON ist ein strenges Format: Ein Komma an der falschen Stelle, und die ganze Datei wird abgelehnt. Die Fehlermeldungen helfen dabei wenig. Chrome meldet das eine, Python etwas anderes, und PHP sagt oft nur „Syntax error“. Um herauszufinden, was die Meldungen wirklich bedeuten, haben wir 26 kurze Schnipsel mit den häufigsten Fehlern geschrieben und sie mit Chrome 141, Node.js 22 (beide nutzen die Engine V8, wie auch Microsoft Edge), Python 3.13 und PHP 8.3 eingelesen. Ihr eigenes JSON können Sie in unseren JSON-Formatter einfügen: Er markiert Zeile und Spalte des ersten Fehlers und nennt die wahrscheinliche Ursache auf Deutsch.
So sieht gültiges JSON aus
JSON ist in zwei Dokumenten festgelegt, die übereinstimmen: RFC 8259 der IETF und ECMA-404. Die Regeln passen auf eine Bildschirmseite:
- Ein JSON-Text ist genau ein Wert: ein Objekt
{…}, ein Array[…], ein Text (String), eine Zahl,true,falseodernull. - Texte und Eigenschaftsnamen stehen in geraden doppelten Anführungszeichen
". Einfache und typografische Anführungszeichen sind nicht erlaubt. - Einträge werden durch Kommas getrennt, aber nach dem letzten Eintrag steht kein Komma.
- Es gibt keine Kommentare.
- Zahlen sind Dezimalzahlen mit Punkt: keine führenden Nullen (
007), kein Dezimalkomma, kein Hexadezimal (0xFF), keinNaNund keinInfinity. - In Texten müssen Anführungszeichen, Backslashes und Steuerzeichen wie Zeilenumbrüche und Tabs maskiert werden:
\",\\,\n,\t. - Leerzeichen, Tabs und Zeilenumbrüche zwischen den Einträgen sind überall erlaubt.
Vieles, was wie JSON aussieht, ist keines: ein JavaScript-Objektliteral, ein mit print() ausgegebenes Python-Dictionary, eine Konfigurationsdatei mit Kommentaren. Das ist nah genug dran, um das Auge zu täuschen, und weit genug weg, um an jedem Parser zu scheitern.
Derselbe Fehler, drei verschiedene Meldungen
Das haben die drei Parser bei den häufigsten Fehlern gemeldet. Chrome und Node.js lieferten in jedem Fall identische Meldungen.
| Fehler | Chrome / Node.js | Python 3.13 | PHP 8.3 |
|---|---|---|---|
Komma vor }: {"age": 31,} | Expected double-quoted property name in JSON at position 11 (line 1 column 12) | Illegal trailing comma before end of object: line 1 column 11 (char 10) | Syntax error |
Komma vor ]: [1, 2, 3,] | Unexpected token ']', "[1, 2, 3,]" is not valid JSON | Illegal trailing comma before end of array | Syntax error |
Einfache Anführungszeichen: {'name': 'Anna'} | Expected property name or '}' in JSON at position 1 | Expecting property name enclosed in double quotes | Syntax error |
| Fehlendes Komma zwischen zwei Eigenschaften | Expected ',' or '}' after property value in JSON | Expecting ',' delimiter | Syntax error |
// Kommentar in der Datei | Expected property name or '}' in JSON | Expecting property name enclosed in double quotes | Syntax error |
NaN als Wert | Unexpected token 'N', … is not valid JSON | ohne Fehler akzeptiert | Syntax error |
| Zeilenumbruch in einem Text | Bad control character in string literal in JSON | Invalid control character at | Control character error, possibly incorrectly encoded |
Windows-Pfad "C:\Users\anna" | Bad escaped character in JSON | Invalid \escape | Syntax error |
| Zwei Objekte hintereinander | Unexpected non-whitespace character after JSON | Extra data | Syntax error |
| Leere Eingabe | Unexpected end of JSON input | Expecting value: line 1 column 1 (char 0) | Syntax error |
| Eine HTML-Seite statt JSON | Unexpected token '<', "<!DOCTYPE "... is not valid JSON | Expecting value: line 1 column 1 (char 0) | Syntax error |
Zwei Dinge fallen auf. Python ist am hilfreichsten: Es benennt das überzählige Komma und die Byte-Order-Mark ausdrücklich. PHP sagt fast immer nur „Syntax error“, die Stelle müssen Sie selbst suchen. Und Python hat NaN akzeptiert, obwohl das kein gültiges JSON ist. Dazu weiter unten mehr.
So lesen Sie eine Fehlermeldung
Enthält eine Meldung eine Position, zählt sie die Zeichen ab null: „position 11“ ist das 12. Zeichen, deshalb ergänzt Chrome „line 1 column 12“. Python zählt Zeilen und Spalten ebenfalls ab eins, meldet aber das Komma selbst (Spalte 11). Die Position markiert die Stelle, an der der Parser aufgegeben hat, und die liegt oft etwas hinter dem eigentlichen Fehler:
- Ein Komma vor einer schließenden Klammer wird in Chrome an der Klammer gemeldet, weil der Parser erst dort merkt, dass statt einer weiteren Eigenschaft
}kommt. - Ein fehlendes Komma wird am Anfang des nächsten Eintrags gemeldet, nicht am Ende des vorherigen.
- Eine fehlende schließende Klammer wird ganz am Ende des Textes gemeldet, egal wie weit oben sie fehlt.
Ein Detail bei Texten mit Emojis: JavaScript zählt ein Emoji als zwei Zeichen, nach einem Emoji ist die Spaltenangabe von Chrome deshalb um eins zu hoch. Python und unser Formatter zählen es als ein Zeichen.
Ältere Browserversionen formulieren dieselben Fehler anders. Der Klassiker ist „Unexpected token < in JSON at position 0“; er bedeutet dasselbe wie die HTML-Zeile in der Tabelle: Der Text beginnt mit <.
Die häufigsten Ursachen und ihre Lösung
Komma nach dem letzten Eintrag
JavaScript erlaubt ein Komma nach dem letzten Eintrag eines Objekts oder Arrays, JSON nicht. Es entsteht meist, wenn Zeilen von Hand gelöscht oder umsortiert werden. Entfernen Sie das Komma vor } oder ].
Einfache und typografische Anführungszeichen
JSON akzeptiert nur das gerade doppelte Anführungszeichen ". Deutsche Anführungszeichen („ “) und andere typografische Varianten schleichen sich ein, wenn JSON durch Word, ein Chatprogramm oder einen E-Mail-Client kopiert wird, der Anführungszeichen automatisch „verschönert“. Fügen Sie solchen Text zuerst in einen reinen Texteditor ein oder ersetzen Sie die Zeichen dort.
JavaScript-Objekte und Python-Dictionaries
Eigenschaftsnamen ohne Anführungszeichen ({name: "Anna"}) sind gültiges JavaScript, aber kein JSON. In Python erzeugt print(daten) oder str(daten) einfache Anführungszeichen sowie True, False und None, alles ungültig. Verwenden Sie JSON.stringify() in JavaScript und json.dumps() in Python; beide schreiben immer echtes JSON.
Kommentare
Standard-JSON kennt keine Kommentare. Manche Programme verwenden erweiterte Formate, die sie erlauben, zum Beispiel das „JSON with Comments“, das Visual Studio Code für seine Einstellungen nutzt, oder tsconfig.json in TypeScript-Projekten. Deshalb funktioniert eine Datei im einen Programm und scheitert im anderen. Entfernen Sie // … und /* … */, bevor die Daten an einen Standard-Parser gehen.
NaN, Infinity und undefined
JSON kann „keine Zahl“ oder „unendlich“ nicht darstellen. JavaScript weiß das: JSON.stringify() schreibt stattdessen null. Python nicht: json.dumps(float('nan')) schreibt NaN, das Python selbst klaglos wieder einliest, das aber jeder Browser ablehnt. Mit allow_nan=False in json.dumps() bekommen Sie stattdessen eine Fehlermeldung. undefined ist überhaupt kein JSON-Wert; JSON.stringify() lässt solche Eigenschaften einfach weg.
Führende Nullen und Dezimalkomma
Postleitzahlen wie 01067 (Dresden) oder Telefonnummern mit führender 0 sind im Sinne von JSON keine Zahlen. Schreiben Sie sie als Text: "plz": "01067". Eine typisch deutsche Falle ist das Dezimalkomma: {"preis": 0,5} wird als Zahl 0 gefolgt von einem Komma gelesen, danach erwartet der Parser einen neuen Eigenschaftsnamen. Schreiben Sie 0.5. Beim Export aus Excel oder einer Tabelle mit deutschen Ländereinstellungen lohnt sich ein Blick darauf.
Zeilenumbrüche und Backslashes in Texten
Ein echter Zeilenumbruch oder Tab innerhalb eines Textes ist nicht erlaubt; schreiben Sie \n und \t. Ein Backslash leitet eine Escape-Sequenz ein, ein Windows-Pfad braucht ihn deshalb doppelt: "C:\\Users\\anna", oder Sie nehmen normale Schrägstriche, die Windows an den meisten Stellen ebenfalls versteht.
HTML statt JSON
Zeigt der Fehler auf das allererste Zeichen und nennt <, hat der Server gar kein JSON geschickt, sondern meist eine HTML-Seite: eine 404- oder 500-Fehlerseite, eine Anmeldeseite oder einen Wartungshinweis. Prüfen Sie den Statuscode und den Header Content-Type der Antwort, bevor Sie nach einem Syntaxfehler suchen.
Unsichtbare Zeichen
Manche Editoren und Exportfunktionen speichern Dateien als „UTF-8 mit BOM“: mit einer unsichtbaren Byte-Order-Mark (U+FEFF) am Dateianfang. JSON.parse() lehnt sie ab, und Pythons Meldung nennt sogar die Lösung: die Datei mit utf-8-sig dekodieren. Laut RFC 8259 dürfen Programme JSON, das sie versenden, keine BOM voranstellen. Unser Formatter entfernt sie und weist darauf hin.
Andere unsichtbare Zeichen sind außerhalb von Texten genauso fatal. In unseren Tests lehnten Chrome und Python ein geschütztes Leerzeichen (U+00A0) ab, das oft mitkommt, wenn man Code aus einer Webseite oder einem Dokument kopiert, ebenso Zeichen mit null Breite und Richtungszeichen, wie sie Editoren für Arabisch oder Persisch einfügen. Innerhalb von Texten sind alle erlaubt. Zeigt der Fehler auf eine Stelle, an der Sie nichts Falsches sehen, löschen Sie das Leerzeichen dort und tippen Sie es neu.
Mehr als ein Wert
Zwei Objekte hintereinander sind kein JSON-Text. Logdateien und Datenexporte nutzen oft JSON Lines (auch NDJSON) mit einem Objekt pro Zeile. Solche Dateien sind in Ordnung, aber jede Zeile muss einzeln eingelesen werden.
Gültig, aber trotzdem überraschend
Manches JSON ist gültig und tut trotzdem nicht, was Sie erwarten:
| Eingabe | Chrome / Node.js | Python 3.13 | PHP 8.3 |
|---|---|---|---|
{"a": 1, "a": 2} | a ist 2 | a ist 2 | a ist 2 |
{"id": 12345678901234567890} | 12345678901234567000 | 12345678901234567890 (exakt) | 1.2345678901234567E+19 (Gleitkommazahl) |
Die zweite Zeile ist in der Praxis wichtig. JavaScript und PHP speichern Zahlen als 64-Bit-Gleitkommazahlen, die nur bis 9.007.199.254.740.991 (2^53 − 1) exakt sind. RFC 8259 empfiehlt, innerhalb dieses Bereichs zu bleiben. Große IDs, etwa aus Datenbanken oder sozialen Netzwerken, sollten Sie deshalb als Text übertragen.
In die andere Richtung lässt JSON.stringify() Eigenschaften mit dem Wert undefined oder einer Funktion stillschweigend weg, macht aus NaN und Infinity ein null und aus Datumsobjekten Texte. Ein BigInt löst sogar einen Fehler aus („Do not know how to serialize a BigInt“).
Checkliste, wenn JSON abgelehnt wird
- Prüfen Sie, ob wirklich JSON angekommen ist: Statuscode 200 und
Content-Typeapplication/json. - Fügen Sie den Text in einen Formatter ein und sehen Sie sich die gemeldete Zeile und das Zeichen davor an.
- Suchen Sie die üblichen Verdächtigen: Komma am Ende, einfache oder typografische Anführungszeichen, ein Kommentar, ein Name ohne Anführungszeichen.
- Prüfen Sie die Werte:
True/Noneaus Python,NaN, Zahlen mit führender Null oder Dezimalkomma. - Prüfen Sie die Texte: echte Zeilenumbrüche, einfache Backslashes in Pfaden, unsichtbare Leerzeichen.
- Korrigieren Sie das Programm, das das JSON erzeugt, damit der Fehler nicht wiederkommt:
JSON.stringify(),json.dumps()oderjson_encode()statt JSON von Hand zusammenzusetzen.
Tools aus diesem Ratgeber
Häufige Fragen
Warum erlaubt JSON kein Komma nach dem letzten Eintrag?
Die Grammatik in RFC 8259 und ECMA-404 sieht es schlicht nicht vor, und das Format wird bewusst nicht verändert, damit jeder Parser dieselben Daten gleich liest. Erweiterte Formate wie JSON5 erlauben Kommas am Ende und Kommentare, ein Standard-JSON-Parser lehnt sie aber ab.
Kann ich Kommentare in JSON schreiben?
Nicht in Standard-JSON. Manche Programme akzeptieren Kommentare in ihren eigenen Konfigurationsdateien, etwa die Einstellungen von Visual Studio Code oder die tsconfig.json von TypeScript. Daten für eine API oder für JSON.parse() dürfen aber keine enthalten. Wenn Sie Notizen brauchen, legen Sie eine normale Eigenschaft wie "_kommentar" an.
Was bedeutet „Unexpected token < in JSON at position 0“?
Der Text beginnt mit „<“ und ist damit fast sicher HTML, etwa eine Fehler- oder Anmeldeseite, und kein JSON. Neuere Chrome-Versionen schreiben Unexpected token '<', "<!DOCTYPE "... is not valid JSON. Prüfen Sie die aufgerufene Adresse und den Statuscode der Antwort.
Warum akzeptiert Python NaN, wenn Browser es ablehnen?
Das json-Modul von Python liest und schreibt NaN, Infinity und -Infinity standardmäßig mit ihren JavaScript-Namen, obwohl sie nicht zum JSON-Standard gehören. Mit json.dumps(daten, allow_nan=False) stellen Sie sicher, dass Sie nur gültiges JSON erzeugen.
Wird mein JSON beim Formatieren irgendwohin hochgeladen?
Nein. Unser JSON-Formatter läuft vollständig in Ihrem Browser. Der Text wird auf Ihrem Gerät geprüft und formatiert und nicht an einen Server geschickt.
Warum ist meine große ID nach dem Einlesen eine andere Zahl?
JavaScript speichert alle Zahlen als 64-Bit-Gleitkommazahlen, die nur bis 9.007.199.254.740.991 exakt sind. Größere ganze Zahlen werden gerundet. Übertragen Sie solche IDs als Text, zum Beispiel "id": "12345678901234567890".
Quellen und weiterführende Informationen
- RFC 8259 – The JavaScript Object Notation (JSON) Data Interchange Format (www.rfc-editor.org)
- ECMA-404 – The JSON data interchange syntax (2nd edition, 2017) (ecma-international.org)
- MDN Web Docs: JSON.parse() (developer.mozilla.org)
- Python documentation: json – JSON encoder and decoder (docs.python.org)