stride3d/stride · warning · IOException
Crash report upload timed out.
Error message
Crash report upload timed out.
What it means
If the crash-report upload finished with zero successful landings and no recorded exception, ThrowIfNothingLanded reports it as a timeout: no part of the report reached the server within the allowed time.
Solutions
- Retry the upload (or leave the run directory for a later session's retry)
- Check network/proxy configuration for silently dropping firewalls
- Increase the upload timeout budget if the environment is slow, or send reports asynchronously at next startup
Example fix
// before
await sender.SendAsync(report); // blocks shutdown on slow network
// after
try { await sender.SendAsync(report); }
catch (IOException e) when (e.Message.Contains("timed out")) { /* defer to next launch */ } Defensive patterns
Strategy: retry
Validate before calling
// pre-check endpoint reachability before attempting upload
using var ping = new HttpClient { Timeout = TimeSpan.FromSeconds(5) };
var reachable = await ping.GetAsync(dsnEndpoint) is { } resp; Try / catch
try { await sender.SendAsync(report); }
catch (IOException e) when (e.Message.Contains("timed out"))
{ /* schedule retry at next startup */ } Prevention
- Defer uploads off the critical crash path
- Retry pending run directories at next launch
- Monitor/verify the report endpoint is not silently blocked by firewalls
When it happens
Trigger: SendCoreAsync completes but succeeded == 0 and failure == null — all upload attempts neither failed explicitly nor landed, typically because requests exceeded the timeout window or were abandoned.
Common situations: Very slow or partially blocked networks; firewall silently dropping packets instead of refusing; an unreachable Sentry endpoint where connections hang rather than error.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Crash report upload failed:
- Connection router did not connect back to our listen socket
- Could not restore package
- GlobalMutex.Wait() is implemented only for…
- ' ' has no parent app directory.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/51da153f65609c7e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/crashreport/Stride.CrashReport/CrashReportSender.cs:211
if (response.IsSuccessStatusCode)
Interlocked.Increment(ref succeeded);
else
failure ??= $"HTTP {(int)response.StatusCode} {response.ReasonPhrase}";
return response;
}
catch (Exception exception)
{
failure ??= exception.Message;
throw;
}
}
public void ThrowIfNothingLanded()
{
if (failure != null)
throw new IOException("Crash report upload failed: " + failure);
if (succeeded == 0)
throw new IOException("Crash report upload timed out.");
}
}
/// <summary>
/// Maps report entries onto Sentry structures: searchable tags, GPU/memory contexts, log lines and
/// undo/redo actions as breadcrumbs, everything else as extra data. The full report text stays
/// attached as report.txt, which is exactly what the window's View report shows.
/// </summary>
private static void MapReport(Scope scope, CrashReportData report)
{
var gpus = new Dictionary<string, Dictionary<string, string>>();
var memory = new Dictionary<string, string>();
string activeAdapter = null;
foreach (var (key, value) in report.Data)
{
switch (key)
{View on GitHub (pinned to 96fad776d2)