Skip to content

Element X iOS cannot make calls: "MISSING_MATRIX_RTC_TRANSPORT" due to missing Authorization header on /rtc/transports #3930

Description

@UrusovVladimir

Description

When trying to make a call using Element X (on any device), an error occurs:
The server is not configured to work with Element Call. Please contact your server admin (Error Code: MISSING_MATRIX_RTC_TRANSPORT).

Steps to reproduce

  1. Log in to the account on the server synapse.myserver.test.ru.
  2. Create a room and attempt to make a call.

Expected behavior

The call successfully connects using the configured LiveKit server.

Actual behavior

An error MISSING_MATRIX_RTC_TRANSPORT appears. The client cannot retrieve the list of RTC transports.

Client logs (critical!)

The client and server logs show that the request to /_matrix/client/unstable/org.matrix.msc4143/rtc/transports does NOT contain an Authorization header, causing the server to return 401 Missing access token.

Synapse server log:

SynapseError: 401 - Missing access token
GET /_matrix/client/unstable/org.matrix.msc4143/rtc/transports

Element X client log:

[ElementCall]: [LocalTransport] Unexpected error fetching RTC transports from backend {"httpStatus":401,"url":"https://synapse.myserver.test.ru/_matrix/client/unstable/org.matrix.msc4143/rtc/transports","errcode":"M_MISSING_TOKEN","error":"Missing access token"}

Server configuration

  • Synapse version: 1.151.0
  • LiveKit: latest version
  • Reverse-Proxy: Nginx Proxy Manager
  • Experimental features enabled:
    • msc4143_enabled: true
    • msc3266_enabled: true
    • msc4222_enabled: true
    • msc4140_enabled: true
  • /.well-known/matrix/client file (available via HTTPS, correct):
    {
        "m.homeserver": {
            "base_url": "https://synapse.myserver.test.ru"
        },
        "io.element.e2ee": {
            "default": true
        },
        "org.matrix.msc4143.rtc_foci": [
            {
                "type": "livekit",
                "livekit_service_url": "https://rtc.myserver.test.ru/livekit/jwt"
            }
        ]
    }

Tests confirming the server is ready

The server side is configured correctly and complies with the specification. The JWT service is accessible and working.

  1. JWT service is reachable via NPM:

    curl https://rtc.myserver.test.ru/livekit/jwt/healthz
    > HTTP/1.1 200 OK
  2. JWT service responds to POST requests (the M_BAD_JSON error means the server received the request and requires room_id or slot_id, which is correct):

    curl -X POST https://rtc.myserver.test.ru/livekit/jwt/get_token -H "Content-Type: application/json" -d '{"room_id": "!test:synapse.myserver.test.ru"}'
    > {"errcode":"M_BAD_JSON","error":"The request body is missing `room_id` or `slot_id`"}

Additional information

  • The issue occurs on 100% of Element X clients (iOS and Android), ruling out device-specific problems.
  • Calls work in the browser version (Element Web) using the old TURN server, confirming the server is reachable from the internet.
  • The problem is related to an incompatibility in the client's implementation of MSC4143: it fails to authorize the request to fetch the list of transports.

Key conclusion

The Element X client does not add the required Authorization header when making a request to /_matrix/client/unstable/org.matrix.msc4143/rtc/transports. This results in a 401 error and, consequently, the inability to use the configured LiveKit for calls.

I use NPM, may be i did wrong in configuration npm?
` vurusov@matrix:~$ docker exec nginx-proxy-manager cat /data/nginx/proxy_host/5.conf

------------------------------------------------------------

rtc.myserver.test.ru

------------------------------------------------------------

map $scheme $hsts_header {
https "max-age=63072000; preload";
}

server {
set $forward_scheme http;
set $server "livekit";
set $port 7880;

listen 80;
listen [::]:80;

listen 443 ssl;
listen [::]:443 ssl;

server_name rtc.myserver.test.ru;
http2 off;

Let's Encrypt SSL

include conf.d/include/letsencrypt-acme-challenge.conf;
include conf.d/include/ssl-cache.conf;
include conf.d/include/ssl-ciphers.conf;
ssl_certificate /etc/letsencrypt/live/npm-19/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/npm-19/privkey.pem;

Asset Caching

include conf.d/include/assets.conf;

Block Exploits

include conf.d/include/block-exploits.conf;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;

access_log /data/logs/proxy-host-5_access.log proxy;
error_log /data/logs/proxy-host-5_error.log warn;

MatrixRTC Authorization Service (JWT)

location ^~ /livekit/jwt/ {
proxy_pass http://lk-jwt-service:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "X-Requested-With, Content-Type, Authorization" always;

}

LiveKit SFU (WebSocket)

location ^~ /livekit/sfu/ {
proxy_pass http://livekit:7880/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_send_timeout 120;
proxy_read_timeout 120;
proxy_buffering off;

}

Перенаправление корня на /livekit/sfu/ (опционально)

location / {
return 302 /livekit/sfu/;
}

Custom

include /data/nginx/custom/server_proxy[.]conf;
} vurusov@matrix:~$ docker exec nginx-proxy-manager cat /data/nginx/proxy_host/2.conf

------------------------------------------------------------

synapse.myserver.test.ru

------------------------------------------------------------

map $scheme $hsts_header {
https "max-age=63072000; preload";
}

server {
set $forward_scheme http;
set $server "matrix-synapse";
set $port 8008;

listen 80;
listen [::]:80;

listen 443 ssl;
listen [::]:443 ssl;

server_name synapse.myserver.test.ru
http2 off;

Let's Encrypt SSL

include conf.d/include/letsencrypt-acme-challenge.conf;
include conf.d/include/ssl-cache.conf;
include conf.d/include/ssl-ciphers.conf;
ssl_certificate /etc/letsencrypt/live/npm-14/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/npm-14/privkey.pem;

Asset Caching

include conf.d/include/assets.conf;

Block Exploits

include conf.d/include/block-exploits.conf;

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;

access_log /data/logs/proxy-host-2_access.log proxy;
error_log /data/logs/proxy-host-2_error.log warn;

location /.well-known/matrix/server {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.server": "https://synapse.myserver.test.ru"}';
}

location /.well-known/matrix/client {
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{
"m.homeserver": {
"base_url": "https://synapse.myserver.test.ru"
},
"io.element.e2ee": {
"default": true
},
"org.matrix.msc4143.rtc_foci": [
{
"type": "livekit",
"livekit_service_url": "https://rtc.myserver.test.ru/livekit/jwt"
}
]
}';
}

proxy_read_timeout 360s;
proxy_buffering off;

location / {

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;


# Proxy!
include conf.d/include/proxy.conf;

}

Custom

include /data/nginx/custom/server_proxy[.]conf;
}`
I would be grateful for any help!BR

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