element-hq / element-hq/element-x-android
QR sign-in silently fails on a LAN homeserver: ACCESS_LOCAL_NETWORK never requested in the QR flow (Android 16/17 Local Network Protection)
- Dominant language
- Kotlin
- Stars
- 2.4k
- Forks
- 624
- Avg merge
- 1d 14h
- Merged PRs (30d)
- 149
Description
### Steps to reproduce
1. Where are you starting? What can you see?
Fresh Element X (never granted the "local network devices" permission), on the sign-in screen. Homeserver is self-hosted (Synapse + Matrix Authentication Service, MSC3861/OIDC, msc4108_enabled) reachable only on a private/LAN address (e.g. https://matrix.example.lan → 192.168.x.x). On a second, already-signed-in device (Element Desktop) open Settings → Sessions → Link new device → Show QR code.
2. What do you click?
In Element X: Sign in → "Sign in with QR code" → scan the QR shown by Element Desktop.
3. More steps…
Element X opens the camera and decodes the QR (logcat shows libzxingcpp load + camera open/close, so the rendezvous URL is read fine), then shows "Establishing a secure connection" and spins forever.
### Outcome
#### What did you expect?
The QR flow should request the Android local-network permission (ACCESS_LOCAL_NETWORK) — as the manual "Enter your account provider" flow does — then connect to the rendezvous and finish signing in.
#### What happened instead?
The rendezvous URL is a private/LAN IP, and Element X hasn't been granted android.permission.ACCESS_LOCAL_NETWORK, so Android silently blocks the connection. Element X sends zero requests to the rendezvous (verified server-side: the QR-showing device polls and gets only 304s; the phone never contacts it). The QR flow never prompts for the permission, so nothing indicates why it fails.
Proof of cause: start a manual sign-in (Sign in → type the homeserver address) — that flow does show the "allow connections to devices on your local network" prompt. Grant it, back out, rescan the QR → connects instantly. Revoking the permission reproduces the hang (dumpsys package io.element.android.x → ACCESS_LOCAL_NETWORK: granted=false); granting it fixes it.
### Your phone model
Google Pixel 7a
### Operating system version
Android 17 (API 37)
### Application version and app store
Element X 26.09.1 - F-Droid (org.fdroid.fdroid)
### Homeserver
Self-hosted Synapse + Matrix Authentication Service (MSC3861 delegated auth, experimental_features.msc4108_enabled: true), on a LAN IP. Server-side MSC4108/rendezvous verified working, Element Desktop completes the flow against the same server.
### Will you send logs?
Yes,
```
### logcat during a QR scan while ACCESS_LOCAL_NETWORK = granted=false
### (device/network identifiers redacted)
08:00:53.988 I/InputDispatcher: ... io.element.android.x/io.element.android.x.MainActivity ...
08:00:57.595 D/CoreBackPreview: Window{io.element.android.x/io.element.android.x.MainActivity}: Setting back callback
08:00:59.618 I/CameraService: CameraService::connect call (PID "io.element.android.x", camera ID 0) Camera API version 2
08:00:59.713 I/CameraService: Start camera streaming for io.element.android.x (UID 10274)
08:00:59.832 D/nativeloader: Load .../io.element.android.x-.../base.apk!/lib/arm64-v8a/libzxingcpp_android.so ... : ok
08:00:59.915 I/CameraService: Stop camera streaming for io.element.android.x (UID 10274)
08:00:59.950 W/DefaultDispatch: avc: denied { search } ... app=io.element.android.x (SELinux cgroup noise, unrelated)
```
### Will you submit a Pull Request?
No
Contributor guide
Research direction
Start at the Element X QR sign-in flow and compare it with the manual “Enter your account provider” flow, which already requests ACCESS_LOCAL_NETWORK. Verify on a LAN homeserver with the permission revoked that scanning a QR code requests permission and then completes the rendezvous sign-in.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android, kotlin
- Domain
- authentication, mobile
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 70/100