Repository navigation
Android: new WebSocket() crashes the app for a URL that OkHttp or java.net.URI rejects #59704
Description
Description
On Android, new WebSocket(url) crashes the app when OkHttp or java.net.URI rejects url, such as ws://localhost:0/ (port 0) or ws://localhost:4000/a|b (a character RFC 2396 doesn't allow in a path). JavaScript gets no exception and no error or close event, and a release build dies with a fatal exception on the native modules thread.
Expected: the socket fires error and close, as it does when it can't connect, or the constructor throws in JavaScript.
Likely cause: WebSocketModule.connect calls Request.Builder().url(url), getCookie, and getDefaultOrigin outside a try, and they throw IllegalArgumentException for such URLs, while send and close catch their exceptions. #24427 reported the same crash in 0.59.
We found this in Evolu, a local-first platform, whose relay URL type now rejects such URLs.
Steps to reproduce
- Replace
App.tsxof an app made from the reproducer template with the code below. - Build it in release for Android and run it.
- Tap either button. The app crashes instead of showing
errorandclose.
import { useState } from 'react';
import { Button, Text, View } from 'react-native';
// Each URL should report an error and close to JS. On Android, connect throws
// natively instead.
const urls = ['ws://localhost:0/', 'ws://localhost:4000/a|b'];
function App() {
const [log, setLog] = useState<ReadonlyArray<string>>([]);
const append = (line: string) => setLog(lines => [...lines, line]);
return (
<View style={{ padding: 48, gap: 16 }}>
{urls.map(url => (
<Button
key={url}
title={url}
onPress={() => {
const socket = new WebSocket(url);
socket.onerror = () => append(`error ${url}`);
socket.onclose = event => append(`close ${url} ${event.code}`);
}}
/>
))}
{log.map((line, index) => (
<Text key={index}>{line}</Text>
))}
</View>
);
}
export default App;React Native Version
0.88.1
Affected Platforms
Runtime - Android, Build - MacOS
Output of npx @react-native-community/cli info
System:
OS: macOS 26.6.2
CPU: (10) arm64 Apple M5
Binaries:
Node: 24.22.0
npmPackages:
react-native: 0.88.1
Android:
hermesEnabled: true
newArchEnabled: true
Device: Android 16 (API 36) arm64 emulator
Stacktrace or Logs
E AndroidRuntime: FATAL EXCEPTION: mqt_v_native
E AndroidRuntime: java.lang.IllegalArgumentException: Invalid URL port: "0"
E AndroidRuntime: at t6.m(r8-map-id-50fb0331…:24)
E AndroidRuntime: at vv.c(r8-map-id-50fb0331…:513)
E AndroidRuntime: at xi.h(r8-map-id-50fb0331…:50)
E AndroidRuntime: at com.facebook.react.modules.websocket.WebSocketModule.connect(r8-map-id-50fb0331…:118)
E AndroidRuntime: at com.facebook.jni.NativeRunnable.run(Native Method)
E AndroidRuntime: at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(…)
E AndroidRuntime: FATAL EXCEPTION: mqt_v_native
E AndroidRuntime: java.lang.IllegalArgumentException: Unable to set ws://localhost:4000/a|b as default origin header
E AndroidRuntime: at com.facebook.react.modules.websocket.WebSocketModule.getCookie(r8-map-id-50fb0331…:8)
E AndroidRuntime: at com.facebook.react.modules.websocket.WebSocketModule.connect(r8-map-id-50fb0331…:121)
MANDATORY Reproducer
No repository: the App.tsx in Steps to reproduce is the whole reproducer.
Screenshots and Videos
No response
Activity
react-native-bot commentedon Oct 30, 2026
Warning
Missing reproducer: We could not detect a reproducible example in your issue report. Reproducers are mandatory and we can accept only one of those as a valid reproducer:
You can read more about about it on our website: How to report a bug.
Add WebSocketUrl and RelayUrl Types to @evolu/common for WebSocket tr…