Entwickeln / Referenz
Fehlercodes
Wie Sie Fehler des Gateways von Fehlern des Anbieters unterscheiden und welche Fehlercodes das Gateway mit welcher Abhilfe sendet.
Fehlerobjekt
Lehnt das Gateway selbst eine Anfrage ab, antwortet es mit einem Fehlerobjekt unter error:
| Feld | Inhalt |
|---|---|
type | immer proxy_error |
code | Fehlercode, zum Beispiel key_budget_exhausted |
message | Beschreibung auf Englisch, oft mit Details zur Anfrage |
Prüfen Sie im Code error.code, nicht message. Der Text von message kann sich ändern, die Codes bleiben stabil. Die Tabelle Alle Fehlercodes nennt Bedeutung und Abhilfe für jeden Code.
Diese Fehler entstehen, bevor oder während das Gateway die Anfrage an einen Anbieter schickt. Bei Fehlerobjekten mit Statuscode 402 oder 403 hat kein Anbieter die Anfrage erhalten.
{
"error": {
"type": "proxy_error",
"code": "key_budget_exhausted",
"message": "This API key has reached its spending limit. …"
}
}Fehler des Anbieters
Antwortet der Anbieter mit einem Fehler, reicht das Gateway Statuscode und Body unverändert durch. Der Body hat dann das Format des Anbieters, nicht das Fehlerobjekt oben. Der Header X-Noirdoc-Provider nennt den Anbieter, der den Fehler gesendet hat.
Bevor ein Fehler Ihre Anwendung erreicht, versucht das Gateway bei Modellen mit mehreren Anbietern den nächsten Anbieter (Failover). Das geschieht bei
- Verbindungsfehlern und Zeitüberschreitungen,
- Statuscode 429 (Too Many Requests),
- allen Statuscodes ab 500.
Andere Statuscodes zwischen 400 und 499 sind die Antwort des Anbieters auf die Anfrage selbst. Das Gateway gibt sie sofort zurück, ohne einen weiteren Anbieter zu fragen. Scheitert auch der letzte Anbieter, erhalten Sie dessen Antwort oder, bei Verbindungsfehlern, provider_unreachable bzw. provider_timeout. Wie viele Anbieter das Gateway höchstens versucht, steht unter Grenzen.
So unterscheiden Sie die beiden Fälle: Nur Fehler des Gateways haben error.type gleich proxy_error.
HTTP/1.1 400 Bad Request
content-type: application/json
x-noirdoc-provider: <anbieter-slug>
{ …Fehler-Body des Anbieters… }Antworten ohne Fehlerobjekt
Zwei Fehlerarten kommen nicht als Fehlerobjekt, sondern mit einem Feld detail:
| Status | Ursache | Body |
|---|---|---|
| 401 | Schlüssel fehlt, ist ungültig oder deaktiviert | {"detail": "Missing or invalid API key"} oder {"detail": "Invalid or inactive API key"} |
| 422 | Body von /v1/detect oder /v1/pseudonymize ungültig | {"detail": […]} mit den fehlerhaften Feldern |
Details zu 401 stehen unter Authentifizierung & Header.
Behandlung im Code
Das Beispiel prüft zuerst, ob das Gateway den Fehler gesendet hat, und reagiert dann auf einzelne Codes. Fehler mit den Statuscodes 502, 503 und 504 sind meist vorübergehend. Senden Sie solche Anfragen mit wachsender Wartezeit erneut. Bei 400, 402, 403 und 404 ändert eine Wiederholung ohne Änderung der Anfrage nichts.
import os
import httpx
API_KEY = os.environ["NOIRDOC_API_KEY"]
response = httpx.post(
"https://api.noirdoc.de/v1/chat/completions",
headers={"Authorization": f"Bearer {API_KEY}"},
json={
"model": "qwen3.8-27b",
"messages": [{"role": "user", "content": "Hallo"}],
},
# Gateway wartet bis zu 120 s je Anbieter,
# bei Failover auf bis zu drei
timeout=400,
)
if response.status_code >= 400:
body = response.json()
error = None
if isinstance(body, dict):
error = body.get("error")
if (
isinstance(error, dict)
and error.get("type") == "proxy_error"
):
code = error["code"]
if code == "key_budget_exhausted":
print("Budget des Schlüssels aufgebraucht.")
elif code in (
"provider_unreachable",
"provider_timeout",
):
print("Kein Anbieter erreichbar, später senden.")
else:
print(f"Gateway-Fehler {code}: {error['message']}")
elif response.status_code == 401:
print(body.get("detail"))
else:
provider = response.headers.get("x-noirdoc-provider")
print(f"Fehler von {provider}: {response.status_code}")const url = "https://api.noirdoc.de/v1/chat/completions";
const res = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.NOIRDOC_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "qwen3.8-27b",
messages: [{ role: "user", content: "Hallo" }],
}),
});
if (!res.ok) {
const body = await res.json();
if (body?.error?.type === "proxy_error") {
switch (body.error.code) {
case "key_budget_exhausted":
console.log("Budget des Schlüssels aufgebraucht.");
break;
case "provider_unreachable":
case "provider_timeout":
console.log("Kein Anbieter erreichbar, später senden.");
break;
default: {
const { code, message } = body.error;
console.log(`Gateway-Fehler ${code}: ${message}`);
}
}
} else if (res.status === 401) {
console.log(body.detail);
} else {
const provider = res.headers.get("x-noirdoc-provider");
console.log(`Fehler von ${provider}: ${res.status}`);
}
}Alle Fehlercodes
Die Tabelle gruppiert die Codes nach Statuscode. Jede Zeile hat einen eigenen Anker, zum Beispiel key_budget_exhausted.
| Code | Bedeutung | Abhilfe |
|---|---|---|
| 400Ungültige Anfrage | ||
invalid_request_path | Der Pfad enthält ein Punkt-Segment (. oder ..), ein %, einen Backslash oder ein Steuerzeichen. | Senden Sie den Pfad ohne Punkt-Segmente und ohne kodierte Zeichen, zum Beispiel /v1/chat/completions. |
model_required | Die Anfrage nennt kein Modell (model im Body, bei /v1/audio/transcriptions im Formularfeld). | Geben Sie eine Modell-ID aus GET /v1/models an. |
wrong_endpoint_for_model | Das Modell gehört zu einer anderen Endpunkt-Familie oder einem anderen API-Format als der aufgerufene Endpunkt. | Rufen Sie das Modell über den passenden Endpunkt auf, zum Beispiel ein Embedding-Modell über /v1/embeddings. |
streaming_not_supported_for_endpoint | Die Anfrage verlangt Streaming, der Endpunkt unterstützt es aber nicht. | Entfernen Sie stream aus der Anfrage. |
invalid_request_body | Der Body ist kein JSON-Objekt oder nicht in UTF-8 kodiert. | Senden Sie den Body als JSON-Objekt in UTF-8 mit Content-Type: application/json. |
invalid_image_request | prompt, n oder size liegt außerhalb der Grenzen des Gateways; message nennt den Parameter. | Korrigieren Sie den genannten Parameter. Teilen Sie große Bildanfragen in mehrere Anfragen auf. |
invalid_tts_request | input oder voice fehlt oder ist leer, oder input ist zu lang. | Senden Sie input und voice als nicht leere Strings und kürzen Sie input auf höchstens 4.096 Zeichen. |
invalid_multipart_body | Der Body ist kein gültiges multipart/form-data, oder model, stream bzw. response_format kommt mehrfach vor. | Senden Sie die Audiodatei als Multipart-Formular mit jedem dieser Felder höchstens einmal. |
| 402Guthaben oder Budget | ||
insufficient_credit | Das Guthaben der Organisation ist aufgebraucht oder kleiner als die geschätzten Höchstkosten der Anfrage. | Laden Sie unter Abrechnung → Aufladen Guthaben auf, oder senken Sie max_tokens bzw. kürzen Sie die Eingabe. |
key_budget_exhausted | Das Budget dieses Schlüssels ist für den laufenden Zeitraum aufgebraucht oder reicht für die geschätzten Kosten der Anfrage nicht aus. | Erhöhen Sie das Ausgabenlimit unter Models → API-Schlüssel, senken Sie max_tokens oder warten Sie auf die nächste Rücksetzung. |
| 403Nicht erlaubt | ||
endpoint_not_available_on_platform | Der Aufruf würde Daten aus dem gemeinsamen Konto eines von Noirdoc verwalteten Anbieters lesen und ist dort gesperrt. | Verbinden Sie unter Models → Provider einen eigenen Anbieter-Schlüssel (BYOK) für diesen Endpunkt. |
reference_not_available_on_platform | Der Body verweist auf Objekte beim Anbieter (etwa conversation, prompt.id oder vector_store_ids), deren Besitz das Gateway bei verwalteten Anbietern nicht prüfen kann. | Entfernen Sie die in message genannten Felder oder verwenden Sie einen eigenen Anbieter-Schlüssel (BYOK). |
model_not_allowed_for_key | Das Modell gehört nicht zu den erlaubten Modellen dieses Schlüssels. | Wählen Sie ein Modell aus GET /v1/models oder erweitern Sie die erlaubten Modelle unter Models → API-Schlüssel. |
provider_not_allowed_for_tenant | Die Organisation gilt als Berufsgeheimnisträger (§ 203 StGB); das schließt jeden Anbieter aus, der dieses Modell anbietet. | Wählen Sie ein Modell aus GET /v1/models. Die Liste enthält nur Modelle mit erlaubten Anbietern. |
provider_not_allowed_for_key | Die Einschränkungen des Schlüssels (Anbieter, Datenresidenz, CLOUD Act, § 203) schließen jeden Anbieter dieses Modells aus. | Wählen Sie ein Modell aus GET /v1/models oder lockern Sie die Einschränkungen unter Models → API-Schlüssel. |
masking_not_supported_for_endpoint | Der Endpunkt kann nicht maskieren, aber die Maskierungsrichtlinie ist enforced oder die Anfrage sendet X-Noirdoc-Mask: on. | Lassen Sie X-Noirdoc-Mask: on weg. Bei enforced kann ein Admin die Richtlinie unter Models → Datenschutz ändern. |
file_content_not_allowed | Die Anfrage enthält Dateien, Bilder oder Audio, und die Organisation lässt keine Dateiinhalte zu. | Senden Sie die Anfrage ohne Dateien, oder lassen Sie einen Admin unter Models → Datenschutz „Dateiinhalte zulassen“ einschalten. |
file_pii_blocked | Eine Datei enthält personenbezogene Daten, und der Dateianalyse-Modus der Organisation ist block. | Entfernen Sie die personenbezogenen Daten aus der Datei, oder lassen Sie den Dateianalyse-Modus unter Models → Datenschutz ändern. |
model_not_billable | Für das Modell ist kein vollständiger Preis hinterlegt, deshalb lässt es sich mit Guthaben nicht nutzen. | Wählen Sie ein anderes Modell oder wenden Sie sich an den Support. |
| 404Nicht gefunden | ||
unsupported_endpoint | Das Gateway kennt diesen Pfad nicht. | Verwenden Sie einen Endpunkt aus der Referenz und prüfen Sie Schreibweise und Präfix /v1/. |
object_not_found | Das Objekt (Datei, Skill oder gespeicherte Antwort) existiert nicht oder gehört nicht Ihrer Organisation. | Prüfen Sie die ID. Verwenden Sie nur IDs, die Ihre Organisation über das Gateway angelegt hat. |
model_not_available | Die Modell-ID ist für die Organisation nicht verfügbar. | Prüfen Sie die Modell-ID mit GET /v1/models. |
| 405Methode nicht erlaubt | ||
method_not_allowed | Der Endpunkt nimmt nur POST an. | Senden Sie die Anfrage mit POST. |
| 413Anfrage zu groß | ||
request_too_large | Der Body überschreitet das Größenlimit des Endpunkts. | Verkleinern oder teilen Sie den Body, etwa die Audiodatei oder eingebettete Dateien. Die Werte stehen unter Grenzen. |
| 422Nicht verarbeitbar | ||
file_unprocessable | Eine Datei ließ sich für die Prüfung nicht verarbeiten: Sie ist zu groß, nicht lesbar oder hat ein Format ohne Analyse. Das Gateway hat die Anfrage nicht weitergeleitet. | Speichern Sie die Datei neu oder in einem anderen Format (etwa PDF, DOCX oder XLSX), verkleinern Sie sie oder entfernen Sie sie, und senden Sie die Anfrage erneut. |
| 500Interner Fehler | ||
detection_error | Die Erkennung personenbezogener Daten ist fehlgeschlagen; das Gateway hat die Anfrage nicht weitergeleitet. | Senden Sie die Anfrage erneut. Bleibt der Fehler bestehen, wenden Sie sich an den Support. |
file_analysis_error | Reserviert für Fehler der Dateianalyse. Das Gateway sendet diesen Code derzeit nicht. | Senden Sie die Anfrage erneut. |
| 502Anbieterfehler | ||
provider_not_configured | Für diese Anfrage ist in der Organisation kein passender Anbieter eingerichtet. | Verbinden Sie unter Models → Provider einen Anbieter für dieses API-Format. |
provider_misconfigured | Die Konfiguration des gewählten Anbieters ist ungültig, zum Beispiel eine nicht erlaubte Basis-URL. | Prüfen Sie Basis-URL und Einstellungen des Anbieters unter Models → Provider. Betrifft es einen von Noirdoc verwalteten Anbieter, wenden Sie sich an den Support. |
provider_unreachable | Das Gateway konnte keine Verbindung zum Anbieter herstellen, oder die Verbindung ist abgebrochen. | Senden Sie die Anfrage nach einer kurzen Wartezeit erneut. |
| 503Vorübergehend nicht verfügbar | ||
provider_auth_unavailable | Die Zugangsdaten des Gateways für den Anbieter sind gerade nicht verfügbar. | Senden Sie die Anfrage später erneut. |
ownership_check_unavailable | Das Gateway konnte gerade nicht prüfen, ob das Objekt Ihrer Organisation gehört, und hat die Anfrage abgelehnt. | Senden Sie die Anfrage erneut. |
| 504Zeitüberschreitung | ||
provider_timeout | Der Anbieter hat nicht innerhalb der Wartezeit des Gateways geantwortet. | Senden Sie die Anfrage erneut. |