title: WebRTC on AWS EC2 with TURN server on AWS EC2 on 2 different networks, error: ICE failed, add a STUN server
body: <p>Currently I have a videochat web app using WebRTC and written in Reactjs deployed on an AWS EC2 Instance. The videochat works with two users on two different computers on a local network or the same internet network and we can easily talk and see each other.</p>
  
  <p>However when I try to videochat with another user who is on a different network, the videochat stops working and I got an error message in my Chrome browser console like this:</p>
  
  <pre><code>Uncaught (in promise) DOMException: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Error processing ICE candidate
  </code></pre>
  
  <p>and the other user gets: </p>
  
  <pre><code>ICE failed, add a STUN server and see about:webrtc for more details
  </code></pre>
  
  <p>I believe the issue is with the TURN server, however I have set up the TURN server using COTURN (<a href="https://github.com/coturn/coturn" rel="nofollow noreferrer">https://github.com/coturn/coturn</a>) on an AWS EC2 instance and it seems to work when I test it on <a href="https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/" rel="nofollow noreferrer">https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/</a> with the same credentials when I try to see for relays.</p>
  
  <p>I deployed the TURN server using instructions from this stackoverflow post:
  <a href="https://stackoverflow.com/questions/31161864/how-to-create-stun-turn-server-instance-using-aws-ec2">How to create stun turn server instance using AWS EC2</a></p>
  
  <p>I have also allowed inbound port access for UDP and TCP for a large range of ports on AWS security groups.</p>
  
  <p>Some relevant code, this one processes the responses I get back from a WebRTC signalling server:</p>
  
  <pre><code>/**
       * Parse a broadcast message and reply back with
       * the appropriate details
       */
      receiveBroadcast(packetObject) {
          try {
              var payload = JSON.parse(packetObject.Payload)
          } catch (err) {
              var payload = packetObject.Payload
          }
  
          if (payload.Type == 'Ice Offer') {
              // Set remote descriptions and construct an ICE answer
              var icePacket = new this.rtcSessionDescription({
                  type: payload.IcePacket.type,
                  sdp: payload.IcePacket.sdp,
              })
  
              this.peerConnection.setRemoteDescription(icePacket, function () {
                  this.peerConnection.createAnswer(this.onCreateAnswerSuccess.bind(this), this.onCreateSessionDescriptionError)
              }.bind(this), this.onSetSessionDescriptionError)
  
  
          } else if (payload.Type == 'Ice Answer') {
              // Set the remote description
              var icePacket = new this.rtcSessionDescription({
                  type: payload.IcePacket.type,
                  sdp: payload.IcePacket.sdp,
              })
  
              this.peerConnection.setRemoteDescription(icePacket, function () {
                  this.onSetRemoteSuccess()
              }.bind(this), this.onSetSessionDescriptionError)
          } else if (payload.Type == 'Ice Candidate') {
  
              console.log('ICE payload :')
              console.log(payload)
  
              // Add the candidate to the list of ICE candidates
              var candidate = new this.rtcIceCandidate({
                  sdpMLineIndex: payload.sdpMLineIndex,
                  sdpMid: payload.sdpMid,
                  candidate: payload.candidate,
              })
              this.peerConnection.addIceCandidate(candidate)
          }
      }
  </code></pre>
  
  <p>Its mainly the last line that is not working.</p>
  
  <p>I set up console.logs to see what the process looks like:</p>
  
  <pre><code>Local stream set
  bundle.js:1 Video Set
  bundle.js:1 setRemoteDescription complete
  bundle.js:1 ICE payload :
  bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:0 1 UDP 2122252543 xxx.xxx.x.xx 57253 typ host", sdpMid: "0"}
  bundle.js:1 ICE payload :
  bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:1 1 UDP 2122187007 xx.xxx.x.xx 53622 typ host", sdpMid: "0"}
  bundle.js:1 ICE payload :
  bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:2 1 TCP 2105524479 xxx.xxx.x.xx 9 typ host tcptype active", sdpMid: "0"}
  bundle.js:1 ICE payload :
  bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "candidate:3 1 TCP 2105458943 xx.xxx.x.xx 9 typ host tcptype active", sdpMid: "0"}
  bundle.js:1 ICE payload :
  bundle.js:1 {Type: "Ice Candidate", sdpMLineIndex: 0, candidate: "", sdpMid: "0"}
  </code></pre>