On Android release builds, Colyseus Godot native clients may fail to connect to wss:// endpoints with:
error 0: CertificateBundleLoadFailure
This happens before any room join succeeds. Multiple room/client instances fail with the same error, which suggests the failure is in TLS certificate bundle loading, not in room logic, auth, networking retries, or server protocol handling.
The issue appears device- or runtime-dependent: the same Android release build works for some users, but fails consistently for others.
Observed Behavior
In an Android release build using Godot 4.6.2-stable, all Colyseus rooms fail immediately after connecting:
status=connecting
status=error 0: CertificateBundleLoadFailure
The failure happens for multiple independent rooms using the same wss:// endpoint.
Diagnostics show:
os=Android
debug=false
endpoint=wss://example.com
last_error_code=0
last_error_message=CertificateBundleLoadFailure
connected=false
Expected Behavior
A Colyseus client using a valid public TLS endpoint should load CA roots and complete the WSS handshake, either by:
using Android system trust roots,
using the embedded Mozilla CA bundle,
or honoring network/tls/certificate_bundle_override.
Important Finding
The Android .so appears to include embedded Mozilla CA PEM data and strings such as:
Using bundled Mozilla CA certificates
network/tls/certificate_bundle_override
CertificateBundleLoadFailure
BEGIN CERTIFICATE
However, on affected Android release builds the client still fails with CertificateBundleLoadFailure.
Workaround Attempted
A client-side bootstrap was added before creating any Colyseus client:
const SOURCE_CERT_BUNDLE := "res://assets/certs/cacert.pem"
const USER_CERT_BUNDLE := "user://tls/cacert.pem"
DirAccess.make_dir_recursive_absolute("user://tls")
var source := FileAccess.open(SOURCE_CERT_BUNDLE, FileAccess.READ)
var data := source.get_buffer(source.get_length())
var target := FileAccess.open(USER_CERT_BUNDLE, FileAccess.WRITE)
target.store_buffer(data)
ProjectSettings.set_setting(
"network/tls/certificate_bundle_override",
USER_CERT_BUNDLE
)
The CA bundle is included in mobile exports:
include_filter="assets/certs/*.pem"
Diagnostics confirmed the file was copied successfully:
tls_override enabled=true configured=true path=user://tls/cacert.pem bytes=189462 error=
However, affected Android clients still failed with:
error 0: CertificateBundleLoadFailure
This suggests that either network/tls/certificate_bundle_override is not honored on Android in this path, user:// paths are not accepted by the native extension, or TLS/certificate initialization happens before the override is read.
Proposed Fix
In the native Godot Colyseus extension:
Ensure Android release builds can reliably load CA roots for WSS.
Prefer Android system trust store when available.
If using embedded Mozilla CA data, ensure it is available and parsed correctly on Android release builds.
Ensure network/tls/certificate_bundle_override is documented and works on Android, including what path formats are supported.
Consider logging the exact certificate source attempted and the low-level parse/open failure when CertificateBundleLoadFailure occurs.
Why This Matters
The failure occurs before Colyseus room logic runs, so frontend retry/reconnect logic cannot recover from it. The user only sees multiplayer unavailable, while the root cause is TLS initialization/certificate loading.
On Android release builds, Colyseus Godot native clients may fail to connect to
wss://endpoints with:This happens before any room join succeeds. Multiple room/client instances fail with the same error, which suggests the failure is in TLS certificate bundle loading, not in room logic, auth, networking retries, or server protocol handling.
The issue appears device- or runtime-dependent: the same Android release build works for some users, but fails consistently for others.
Observed Behavior
In an Android release build using Godot 4.6.2-stable, all Colyseus rooms fail immediately after connecting:
The failure happens for multiple independent rooms using the same wss:// endpoint.
Diagnostics show:
Expected Behavior
A Colyseus client using a valid public TLS endpoint should load CA roots and complete the WSS handshake, either by:
using Android system trust roots,
using the embedded Mozilla CA bundle,
or honoring network/tls/certificate_bundle_override.
Important Finding
The Android .so appears to include embedded Mozilla CA PEM data and strings such as:
However, on affected Android release builds the client still fails with CertificateBundleLoadFailure.
Workaround Attempted
A client-side bootstrap was added before creating any Colyseus client:
The CA bundle is included in mobile exports:
include_filter="assets/certs/*.pem"
Diagnostics confirmed the file was copied successfully:
However, affected Android clients still failed with:
This suggests that either network/tls/certificate_bundle_override is not honored on Android in this path, user:// paths are not accepted by the native extension, or TLS/certificate initialization happens before the override is read.
Proposed Fix
In the native Godot Colyseus extension:
Ensure Android release builds can reliably load CA roots for WSS.
Prefer Android system trust store when available.
If using embedded Mozilla CA data, ensure it is available and parsed correctly on Android release builds.
Ensure network/tls/certificate_bundle_override is documented and works on Android, including what path formats are supported.
Consider logging the exact certificate source attempted and the low-level parse/open failure when CertificateBundleLoadFailure occurs.
Why This Matters
The failure occurs before Colyseus room logic runs, so frontend retry/reconnect logic cannot recover from it. The user only sees multiplayer unavailable, while the root cause is TLS initialization/certificate loading.