Quick answer: HTTPS requests fail on mobile because the export lacks a TLS certificate bundle. Set a certificate bundle path in Project Settings > Network > TLS, set a reasonable timeout on the HTTPRequest node, and enable the INTERNET permission in your Android export settings.
Here is how to fix Godot HTTPRequest timing out or failing on mobile. Your game makes API calls that work perfectly on desktop. You export to Android or iOS, and every request either hangs forever or immediately returns an error. No data comes back, leaderboards do not load, and analytics events vanish into the void. The game works offline, but anything involving HTTP is dead on arrival.
The Symptom
HTTPRequest’s request_completed signal either never fires (the request hangs indefinitely) or fires immediately with RESULT_TLS_HANDSHAKE_ERROR or RESULT_CONNECTION_ERROR. On Android, HTTPS URLs fail while HTTP URLs sometimes work. On iOS, nothing works because App Transport Security blocks non-HTTPS traffic by default.
The same code works on Windows, macOS, and Linux without issues. The problem only appears in mobile builds.
What Causes This
1. Missing TLS certificate bundle. On desktop, Godot uses the operating system’s certificate store for HTTPS verification. Mobile exports run in a sandboxed environment and do not have access to system certificates. Without a bundled certificate file, Godot cannot verify the server’s TLS certificate and the handshake fails.
2. No timeout set. The default timeout on HTTPRequest is 0, meaning it waits forever. On flaky mobile networks, a request can hang indefinitely. Without a timeout, the player never gets feedback that the request failed.
3. Missing INTERNET permission. On Android, the export must include the INTERNET permission in the manifest. Without it, the OS blocks all network traffic from the app silently.
4. Main-thread blocking. Without use_threads enabled, large responses are processed on the main thread, causing hitches. On mobile where frame budgets are tight, this can look like a freeze or timeout.
The Fix
Step 1: Bundle TLS certificates. Go to Project > Project Settings > Network > TLS. Set the Certificate Bundle path to a CA certificate file. You can download Mozilla’s certificate bundle or use the one included with Godot:
# Download the Mozilla CA bundle
# Place ca-certificates.crt in your project root
# Set in Project Settings > Network > TLS > Certificate Bundle
# Or set it in code before making requests:
func _ready():
var http = $HTTPRequest
http.timeout = 15 # 15-second timeout
http.use_threads = true
http.request_completed.connect(_on_request_completed)
var err = http.request("https://api.example.com/scores")
if err != OK:
print("Request failed to start: %s" % err)
Step 2: Set a timeout and handle failures.
func _on_request_completed(result, response_code, headers, body):
match result:
HTTPRequest.RESULT_SUCCESS:
var json = JSON.parse_string(body.get_string_from_utf8())
print("Got data: %s" % json)
HTTPRequest.RESULT_TIMEOUT:
print("Request timed out - check network connection")
show_retry_dialog()
HTTPRequest.RESULT_TLS_HANDSHAKE_ERROR:
print("TLS error - certificate bundle missing or invalid")
_:
print("HTTP error: result=%d code=%d" % [result, response_code])
Step 3: Enable Android permissions. In the Export dialog, select the Android preset. Under Permissions, check “Access Network State” and “Internet.” Without these, Android blocks all outbound network connections from your app.
Step 4: Enable threading. On the HTTPRequest node in the Inspector, check use_threads. This offloads HTTP processing to a background thread, preventing frame drops on mobile:
# Enable threading in code
$HTTPRequest.use_threads = true
“Desktop gets free TLS certificates from the OS. Mobile does not. If your HTTPS requests work on desktop but fail on mobile, the certificate bundle is always the first thing to check.”
Why This Works
HTTPS requires the client to verify the server’s certificate against a trusted root certificate authority. Desktop operating systems maintain a certificate store that applications can access. Mobile apps run in sandboxes without this access. By bundling a CA certificate file with your Godot project, you provide the trust anchors that the TLS library needs to verify server certificates. Without them, every HTTPS handshake fails because the client cannot trust any server.
The timeout prevents the player from staring at an infinite loading spinner when the network is unavailable. Mobile users frequently switch between Wi-Fi and cellular, enter tunnels, or have spotty coverage. A 10-15 second timeout provides enough time for slow connections while still giving feedback on failures.
Related Issues
If your HTTP requests work but JSON parsing fails on the response, check the encoding. Mobile servers sometimes return gzip-compressed responses that need decompression. Set accept_gzip to false if you are not handling decompression.
For saving data received from HTTP requests to local storage on mobile, see Fix: Godot Custom Resource Not Saving Exported Properties for the correct file paths on Android and iOS.
Bundle the certificates. Set a timeout. Enable INTERNET permission. Mobile HTTP solved.