Skip to content

WHIP output fails to connect when server only provides TURN relay via Link header #12790

@leporel

Description

@leporel

Operating System Info

Windows 11

Other OS

No response

OBS Studio Version

32.0.1

OBS Studio Version (Other)

No response

OBS Studio Log URL

https://obsproject.com/logs/oga2cXY8OfzoIWh6

OBS Studio Crash Log URL

No response

Expected Behavior

OBS should use the TURN server provided in the Link header and establish a connection through the relay when direct UDP connection is not available.

Current Behavior

OBS appears to attempt direct ICE UDP connection despite TURN credentials being provided in the Link header. The connection enters "Connecting" state but never successfully transmits data, eventually failing after ~2 minutes.

Steps to Reproduce

  1. Use only TURN server, provided like described in rfc9725 from header
  2. webrtc server accepts only connection to turn server (in case OME they have ebbeded turn server) (so firewall opens onlly this port of turn server, other ports are deny, except 443 for https for whip)

Anything else we should know?

When attempting to stream using WebRTC WHIP to a server that only provides TURN relay (OvenMediaEngine), the stream is created on the server side but disconnects after approximately 2 minutes without receiving data. The OBS peer appears to disconnect due to a timeout.

Server Response Headers:

Location: /room/[stream-name]?direction=whip
ETag: [etag-value]
Link: <turn:server.example.com:3378?transport=tcp>; rel="ice-server"; username="user"; credential="pass"; credential-type="password"
Access-Control-Expose-Headers: Location, Link, ETag
Vary: Origin
content-type: application/sdp
server: OvenMediaEngine

OBS Logs:

15:05:43.768: [obs-webrtc] [whip_output: 'simple_stream'] PeerConnection state is now: Connecting
15:06:46.767: [obs-webrtc] [whip_output: 'simple_stream'] PeerConnection state is now: Failed
15:06:46.767: Output 'simple_stream': stopping
15:06:46.767: [obs-webrtc] [whip_output: 'simple_stream'] PeerConnection state is now: Closed

Additional Context:

I can see that OBS has ParseLinkHeader in the code, and the server correctly returns TURN credentials in the Link header per WHIP specification. However, OBS still attempts to use direct ICE candidates which are not accessible from the external internet.

In my use case, I need TURN to be used exclusively (relay-only policy) so users stream over TCP. I encountered the same issue when implementing WHIP in a browser, but was able to resolve it by forcing use configured iceServers before creating RTCPeerConnection:

const config = {
  iceServers: [{
    urls: 'turn:server.example.com:3378?transport=tcp',
    username: 'user',
    credential: 'pass'
  }],
  iceTransportPolicy: "relay"
};
new RTCPeerConnection(config);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions