Skip to content

WebSocket.ping() on Android sends an empty binary frame instead of a protocol-level PING #57840

Description

@dekpient

Description

WebSocket.ping() on Android sends an empty binary data frame (opcode 0x2) via OkHttp's
client.send(ByteString.EMPTY), instead of a real RFC 6455 PING control frame (opcode 0x9). On iOS,
ping() correctly sends a protocol-level ping via SocketRocket's sendPing:error:.

This breaks against WebSocket servers that reject binary frames (e.g. AWS API Gateway WebSocket APIs),
which close the connection with code 1003 UNSUPPORTED_DATA instead of responding with a pong.

The incorrect ping() that sends the empty frame is still present on the latest version (v0.86.2) of RN here: https://github.com/react/react-native/blob/v0.86.2/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/WebSocketModule.kt#L327

    try {
      client.send(ByteString.EMPTY)
    } catch (e: Exception) {
      notifyWebSocketFailed(id, e.message)
    }

Steps to reproduce

  1. Connect a WebSocket to a server that rejects binary frames (e.g. AWS API Gateway WS API).
  2. Call webSocket.ping() on Android.
  3. Observe the connection closes with 1003 UNSUPPORTED_DATA instead of receiving a pong.

React Native Version

0.86.2

Affected Platforms

Runtime - Android

Output of npx @react-native-community/cli info

System:
  OS: macOS 26.5.2
  CPU: (12) arm64 Apple M4 Pro
  Memory: 106.66 MB / 24.00 GB
  Shell:
    version: "5.9"
    path: /opt/homebrew/bin/zsh
Binaries:
  Node:
    version: 23.10.0
    path: /opt/homebrew/bin/node
  Yarn:
    version: 1.22.19
    path: /opt/homebrew/bin/yarn
  npm:
    version: 10.9.2
    path: /opt/homebrew/bin/npm
  Watchman:
    version: 2025.05.19.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods: Not Found
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.2
      - iOS 26.2
      - macOS 26.2
      - tvOS 26.2
      - visionOS 26.2
      - watchOS 26.2
  Android SDK: Not Found
IDEs:
  Android Studio: 2024.2 AI-242.23726.103.2422.12816248
  Xcode:
    version: 26.2/17C52
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.14
    path: /Users/inging/.jenv/shims/javac
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

Stacktrace or Logs

Logs from mitmproxy with a custom interceptor script:


<IP_REDACTED>:44604 -> WebSocket binary message -> <WSS_HOST_REDACTED>:443/
Error in WebSocket connection to <WSS_HOST_REDACTED>:443: WebSocket Error: UNSUPPORTED_DATA (reason: Binary is not supported)

MANDATORY Reproducer

https://gist.github.com/dekpient/4b611eb4efb58ecc1a881942f842a595

Screenshots and Videos

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions