Intent to Ship: WebRTC Datachannel: Always negotiate data channels

51 views
Skip to first unread message

Philipp Hancke

unread,
Jan 21, 2026, 6:31:33 AM (yesterday) Jan 21
to blink-dev, Harald Alvestrand
tContact emails
h...@chromium.orgphilipp...@googlemail.com

Specification
https://w3c.github.io/webrtc-extensions/#always-negotiating-datachannels

Summary
Implement https://w3c.github.io/webrtc-extensions/#always-negotiating-datachannels

Blink component
Blink>WebRTC

Web Feature ID
Missing feature

TAG review status
Not applicable (incremental addition to WebRTC)

Risks
Interoperability and Compatibility
No information provided

Gecko: No signal (https://github.com/mozilla/standards-positions/issues/1335)

WebKit: No signal (https://github.com/WebKit/standards-positions/issues/599)

Web developers: No signals


Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, ChromeOS, Android, and Android WebView)?
Yes

Is this feature fully tested by web-platform-tests?
Yes, a WPT is part of https://chromium-review.googlesource.com/c/chromium/src/+/7080041

Rollout plan
Will ship enabled for all users

Requires code in //chrome?
False

Tracking bug
https://issues.chromium.org/issues/433898678

Estimated milestones
Shipping on desktop146

Link to entry on the Chrome Platform Status
https://chromestatus.com/feature/5113419982307328?gate=6516338099093504

This intent message was generated by Chrome Platform Status.

Robert Flack

unread,
Jan 21, 2026, 9:30:20 AM (yesterday) Jan 21
to Philipp Hancke, blink-dev, Harald Alvestrand
The specification just says "alwaysNegotiateDataChannels defines a way for the application to negotiate data channels in the SDP offer before creating a datachannel". I'm finding it a bit hard to reason about what this means for me as a developer. I.e. when should I set it and how does this change the connection? Does this mean that a data channel will be negotiated without calling createDataChannel? Will that requested datachannel result in a datachannel event or does my code still need to call createDataChannel? If the latter, is this a performance optimization? Would I choose this when data is more important to connect first rather than e.g. voice / video?

The linked tracking bug appears to be a chrome-only bug report with a particular demo that doesn't use the alwaysNegotiateDataChannels attribute and works on Firefox. I don't quite understand what the new configuration extension has to do with the original bug report.


--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/CADxkKiKuE79-xWUFiO9NCy%2Big9Pvn1oi6fVbkdomFLo4--bJQw%40mail.gmail.com.

Rick Byers

unread,
Jan 21, 2026, 10:39:31 AM (24 hours ago) Jan 21
to Robert Flack, Philipp Hancke, blink-dev, Harald Alvestrand
This is generally why we require explainers. Part of the point of this launch process is ensuring we've got the public material for web developers to understand the feature. Harald can you post an explainer somewhere which includes answers to Rob's questions?

Thanks,
   Rick

Philipp Hancke

unread,
9:20 AM (1 hour ago) 9:20 AM
to Rick Byers, Robert Flack, blink-dev, Harald Alvestrand
bear with me while I try to explain 15 years of history...

Am Mi., 21. Jan. 2026 um 16:39 Uhr schrieb Rick Byers <rby...@chromium.org>:
This is generally why we require explainers. Part of the point of this launch process is ensuring we've got the public material for web developers to understand the feature. Harald can you post an explainer somewhere which includes answers to Rob's questions?
Thanks,
   Rick

On Wed, Jan 21, 2026 at 9:30 AM Robert Flack <fla...@chromium.org> wrote:
The specification just says "alwaysNegotiateDataChannels defines a way for the application to negotiate data channels in the SDP offer before creating a datachannel". 
I'm finding it a bit hard to reason about what this means for me as a developer. I.e. when should I set it and how does this change the connection?

Lets say you create a RTCPeerConnection. Create an offer and call setLocalDescription. Send it to your peer. You get an answer from the peer and feed it into setRemoteDescription.
You might wonder why it does not result in a connection.

Next, you create a datachannel. Your datachannel never opens because after adding the datachannel (only the first!) you need to call createOffer/setLocalDescription and call setRemoteDescription with the answer.
"web developers" are notably confused:
Now your connection gets established. If you add another data channel you do *not* need to do this negotiation again (thankfully; adding audio or video tracks requires negotiation).

In this case using the boolean flag is saving you one round of negotiation.

In many applications you do not know if you want to use a datachannel but since you might, you preemptively create one and throw it away. You can see that e.g. in Google Meet which calls
   pc.createDataChannel("ignored", {reliable: true})
It never uses that channel but it shows up in the getStats API every time.
 
Does this mean that a data channel will be negotiated without calling createDataChannel?

The underlying SCTP association will be negotiated and can be used by subsequent calls to createDataChannel without renegotiation.
This currently means exchanging four packets over the network (but that upfront cost might go away later this year).
Everything is set up to just work.
 
Will that requested datachannel result in a datachannel event or does my code still need to call createDataChannel? If the latter, is this a performance optimization?

Part of it is a performance / ergonomics optimization. But behold, there comes the 2011 backward compat angle below.
 
Would I choose this when data is more important to connect first rather than e.g. voice / video?

Lets say you have a stream from getUserMedia with audio and video and would also like to have a datachannel.
You call pc.createDataChannel and then iterate over the MediaStream's getTracks and call pc.addTrack with each.
Because data channels were new and fancy in 2011 and backward compat was a concern this results in SDP (due to rules in RFC 8829) which puts the datachannel bits in the SDP after the audio and video bits (and in Safari the order of audio and video bits depend on the lexical ordering of the random uuid of the MediaStreamTrack) so the SDP looks roughly like this:
  v=0 (6 more lines)
  m=audio 9 UDP/TLS/RTP/SAVPF 63 111 (23 more lines) direction=sendonly mid=0
  m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 45 46 (63 more lines) direction=sendonly mid=1
  m=application 9 UDP/DTLS/SCTP webrtc-datachannel (9 more lines) direction=sendrecv mid=2

Which is ok but you are probably scratching your head why this order does not match the order of calls (or why in Safari you get video-audio-application half the time)
https://www.rfc-editor.org/rfc/rfc8829.html#name-initial-offers specifies this (search for "Lastly, ") but does not provide much of a rationale. https://github.com/w3c/webrtc-pc/issues/735 has some 2016 rationale.
Now that seems like an odd choice but had little consequence until...


The linked tracking bug appears to be a chrome-only bug report with a particular demo that doesn't use the alwaysNegotiateDataChannels attribute and works on Firefox. I don't quite understand what the new configuration extension has to do with the original bug report.

WebRTC added APIs that allow you to negotiate codecs at some point. This can result in a situation where you end up with a incompatible set of video codecs (see the bug) and if those happen to be first in the SDP this "m=" line will be marked as "rejected" and can not be used to convey the transport information anymore.
At best this results in another round of negotiation to satisfy

Now 
actually provides a recommendation on how to avoid this: you pick something that is "unlikely to be rejected by the remote side".
The browser does not have an API that would lead to it rejecting a datachannel m= line (which can happen for audio and video)
So it would be great to pick this datachannel m= line as "offerer tagged" which avoids this headache.
But that requires (unless you want to risk more breakage) putting this m= line first which is conflicts with the rules of RFC 8829.
The alternative is going through at least two rounds of negotiation (which involves the remote end), the first datachannel only and then adding media.
Hence you need a way to opt-in which is the boolean in the RTCConfiguration.

Would you like to hear more about why WebRTC is so weird? (a lot of this boils down to "SDP is not an opaque blob)
Reply all
Reply to author
Forward
0 new messages