Understanding onicecandidateerror

🎻 October 2020 fiddle


Want to learn more about WebRTC?

Look us up here for the WebRTC Fiddle of the Month, created… once a month.

Or just enroll to one of our excellent WebRTC training courses.



Tsahi: Hi everyone, and welcome to our Monthly WebRTC Fiddle. This time we’re going to talk about how to understand onicecandidateerror. Philipp, you wanted to do this one, so I’ll directly start with you. Take us through the motion and I will ask questions and bug you.

Philipp: So let’s look at the code we have. We start by setting an array of iceServers, creating it and then creating a peer connection with it.

Tsahi: I see you pick the Google STUN server one.

Philipp: Yes. Everyone loves the Google STUN server for some reason.

Then we create the peer connection and we set the event listeners on it. First is for the onicecandidate event, which is this one.

Tsahi: And we get the candidates, you simply log it to the console.

Philipp: Yes, and when we don’t get a candidate. That means the gathering is finished, which historically means that the candidates property on the event is not set.

And the second one is the onicecandidateerror. Which we simplylog to the console.

This is only implemented in Chrome and the new Edge at the moment. And it might come to Firefox someday, and whenever Safari picks it up.

Tsahi: Probably three years from now.

Philipp: We’ll see. It’s not that important as we’ll see.

Then we create the data channel. So we have something in the SDP which starts candidate gathering. Then we call createOffer(), which creates an offer then we call setLocalDescription() with that offer which starts the ICE candidate gathering.

So let’s run this.

Tsahi: So what we can see here is that we get a couple of candidates.

  1. First, an IPv6 one, it’s the host candidate. So that’s a local IPv6 address
  2. We get an IPv4 address, local one
  3. We get an error event which went on to talk about soon
  4. And we get a server reflexive candidate here, which gives you my public IP address and tells you that the other address associated with is my local IPv4 address
  5. And we get a TCP candidate, which is not very useful for us because. We’re not going to use TCP unless we’re talking to a server which supports ICE-TCP. We get this for both IPv6 and IPv4

And we got this onicecandidateerror() event. So if we expand that one, we can see it’s from and obfuscated IPv6 address. The error code is 701. That’s a very generic error. There are a couple of errors that can have this error code and error text is “STUN host lookup received error.”

What this means is that Chrome tried to look up the IPv6 DNS record for this stunl.google Chrome server and got an error in that process. Probably because my DNS server doesn’t like this IPv6 address.

Tsahi: OK, what are they doing a good this error?

Philipp: The question you should ask is, did you get a server reflexive candidate, which is your goal if you add a STUN server and we got one here. So in this case, we can ignore that error because it’s more for your information and it’s not fatal.

Tsahi: OK. OK, so as long as I get connected, I should ignore these messages or should I ignore them if I simply had other candidates that I expected to receive?

Philipp: Yes, you should ignore them if you have the candidates you expected to receive.

If things fail then this might provide you with additional debug information.

Tsahi: OK. Essentially for us at this point in time with this kind of an error in this kind of scenario, it’s useless.

Philipp: It’s useless, but there are some cases where it’s actually useful.

So let’s go to another fiddle.

Compared to the first fiddle, we changed it to use a TURN server and I made up credentials. Because the server doesn’t support the user name ‘foo’ and the credential ‘bar’.

And if we run that one. You can see we got a server reflexive candidate because every TURN server acts as a STUN server as well for UDP, and we got a number of errors.

So we have the same errors as before these two ones. And we have another one which has a different error code: 401, which is a classic error for authentication code and it says “unauthorized”.

So this tells us that we tried to talk to a TURN server, since we got a server reflexive candidate, we know we can reach the TURN server, but then we got an error, which tells us, ‘oh, we used the wrong credentials’.

Tsahi: OK, so we have a callback, onicecandidateerror that exists only in Chrome and Edge. And it’s not that useful. Unless you’re trying to figure out issues of actual connectivity, then probably, I guess not even for customers, but mostly as you develop, would that be a correct assumption of where this makes sense to look at?

Philipp: Yes. If you debug customer issues, you typically look at what kinds of candidates they gather. So if you have a TURN server that is properly set up and uses UDP, TCP and TLS, you would always do a different thing and check if they got UDP, TCP and TLS candidates from the TURN server. If not, their network was probably blocking things somehow.

Tsahi: OK, thank you very much.

Philipp: Thank you.

Tsahi: See you next month in our next fiddle.