Start · Sprachen · JavaScript · Referenz · RTCPeerConnection: icecandidateerror

RTCPeerConnection: icecandidateerror

Ereignis

Wird an eine <code>RTCPeerConnection</code> gesendet, wenn beim Sammeln von ICE-Kandidaten über einen STUN- oder TURN-Server ein Fehler auftritt.

seit JavaScript Baseline 2023: Chrome 77+, Edge 79+, Firefox 112+, Kategorie: webapi

Signatur

peerConnection.addEventListener("icecandidateerror", handler)

Beschreibung

Das Ereignis icecandidateerror wird ausgelöst, wenn die RTCPeerConnection beim Sammeln von ICE-Kandidaten (ICE Gathering) einen konfigurierten STUN- oder TURN-Server nicht erreicht oder von ihm eine Fehlerantwort bekommt. Typische Ursachen sind ein falscher Hostname, eine gesperrte Firewall, falsche TURN-Anmeldedaten (Fehlercode 401) oder eine Zeitüberschreitung (Fehlercode 701).

Der Handler erhält ein RTCPeerConnectionIceErrorEvent mit den Eigenschaften address, port, url, errorCode und errorText. Daran lässt sich erkennen, welcher Server und welche lokale Netzwerkschnittstelle betroffen sind. Ein Handler lässt sich mit addEventListener("icecandidateerror", …) oder über die Eigenschaft onicecandidateerror registrieren.

Wichtig: Das Ereignis ist nicht zwingend fatal. Die Verbindung kann trotzdem zustande kommen, etwa über andere Kandidaten (Host-Kandidaten, einen anderen Server oder eine andere Schnittstelle). Das Ereignis eignet sich deshalb vor allem für Diagnose, Logging und Monitoring. Ob die Verbindung wirklich gescheitert ist, erkennt man an iceconnectionstatechange bzw. connectionstatechange mit dem Zustand "failed".

Parameter

Name Typ Default Beschreibung
$type Pflicht string Der Ereignisname "icecandidateerror".
$handler Pflicht (event: RTCPeerConnectionIceErrorEvent) => void Callback, der ein RTCPeerConnectionIceErrorEvent erhält, mit address (string|null), port (number|null), url (string), errorCode (number) und errorText (string).
$options boolean|AddEventListenerOptions false Übliche Listener-Optionen wie once oder signal (zum Entfernen über einen AbortController).

Rückgabewert

Typ
void
Beschreibung
addEventListener gibt nichts zurück. Die Fehlerinformationen stehen im übergebenen RTCPeerConnectionIceErrorEvent.

Beispiele

STUN-/TURN-Fehler mit addEventListener protokollieren

const pc = new RTCPeerConnection({
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' },
    { urls: 'turn:turn.example.com:3478', username: 'user', credential: 'falsch' }
  ]
});

pc.addEventListener('icecandidateerror', (event) => {
  const { url, address, port, errorCode, errorText } = event;
  console.warn(`ICE-Fehler ${errorCode} bei ${url} (lokal ${address}:${port}): ${errorText}`);
});

// Kandidatensuche anstoßen
pc.createDataChannel('test');
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
ICE-Fehler 401 bei turn:turn.example.com:3478?transport=udp (lokal 192.168.1.23:52011): Unauthorized

Fehlercodes auswerten und per on-Eigenschaft registrieren

const pc = new RTCPeerConnection({
  iceServers: [{ urls: 'turns:turn.example.com:443', username: 'u', credential: 'p' }]
});

const beschreibeFehler = (code) => {
  if (code === 401) return 'TURN-Anmeldedaten ungültig oder abgelaufen';
  if (code === 701) return 'Server nicht erreichbar (Zeitüberschreitung/DNS)';
  if (code >= 300 && code <= 699) return 'STUN-Fehlerantwort des Servers';
  return 'Unbekannter Fehler';
};

pc.onicecandidateerror = (event) => {
  console.log(`${event.url}: ${beschreibeFehler(event.errorCode)}`);
};

pc.createDataChannel('chat');
await pc.setLocalDescription(await pc.createOffer());
turns:turn.example.com:443?transport=tcp: Server nicht erreichbar (Zeitüberschreitung/DNS)

Fehler sammeln und nur bei endgültigem Scheitern melden

const pc = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.example.org' }] });
const iceFehler = [];
const controller = new AbortController();

pc.addEventListener('icecandidateerror', (e) => {
  iceFehler.push({ url: e.url, code: e.errorCode, text: e.errorText });
}, { signal: controller.signal });

pc.addEventListener('connectionstatechange', () => {
  if (pc.connectionState === 'failed') {
    console.error('Verbindung gescheitert. ICE-Fehler:', iceFehler);
  }
  if (pc.connectionState === 'connected') {
    // Listener entfernen, Fehler waren nicht fatal
    controller.abort();
    console.log(`Verbunden trotz ${iceFehler.length} ICE-Fehler(n).`);
  }
});
Verbunden trotz 1 ICE-Fehler(n).

// Wichtig · Fallstricke

  • Nicht fatal: Ein icecandidateerror bedeutet nicht, dass die Verbindung scheitert. Ob sie wirklich fehlgeschlagen ist, zeigt nur connectionState === "failed". Blende also nicht bei jedem Fehler eine Meldung für Nutzer ein.
  • Fehlercodes: Werte von 300 bis 699 sind STUN-Fehlercodes nach RFC 5389 (z. B. 401 Unauthorized, 438 Stale Nonce). Werte von 700 bis 799 bedeuten, dass der Server gar nicht erreicht wurde (z. B. 701).
  • Datenschutz: address kann null sein oder eine verschleierte mDNS-Adresse (*.local) enthalten, damit keine lokalen IP-Adressen nach außen gelangen.
  • Veraltete Eigenschaft: Ältere Chrome-Versionen hatten hostCandidate statt address/port. Wenn du alte Browser unterstützen musst, prüfe beide.
  • Kompatibilität: Firefox unterstützt das Ereignis erst ab Version 112 und Safari ab 16.4. In älteren Browsern wird es einfach nie ausgelöst.
  • Die Kandidatensuche beginnt erst nach setLocalDescription(). Den Listener daher vorher registrieren.
  • TURN-Anmeldedaten im Frontend-Code sind öffentlich sichtbar. Verwende besser zeitlich begrenzte Anmeldedaten, die dein Server ausstellt.