ppy/osu · warning · WebException

Connection closed by remote host.

Error message

Connection closed by remote host.

What it means

Thrown as WebException by WebSocketNotificationsClient when it receives a Close frame from the remote host. It is the channel for normal and abnormal connection termination, surfaced through InvokeClosed so the connector can reconnect.

Source

Thrown at osu.Game/Online/Notifications/WebSocket/WebSocketNotificationsClient.cs:77

                                Debug.Assert(message != null);

                                if (message.Error != null)
                                {
                                    Logger.Log($"{GetType().ReadableName()} error: {message.Error}", LoggingTarget.Network);
                                    break;
                                }

                                MessageReceived?.Invoke(message);
                            }

                            break;

                        case WebSocketMessageType.Binary:
                            throw new NotImplementedException("Binary message type not supported.");

                        case WebSocketMessageType.Close:
                            throw new WebException("Connection closed by remote host.");
                    }
                }
                catch (Exception ex)
                {
                    await InvokeClosed(ex).ConfigureAwait(false);
                    return;
                }
            }
        }, cancellationToken);

        private async Task closeAsync()
        {
            try
            {
                await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, @"Disconnecting", CancellationToken.None).ConfigureAwait(false);
            }
            catch
            {

View on GitHub (pinned to d9c73e12ad)

Solutions

  1. Treat this as a transient disconnect: let PersistentEndpointClientConnector handle reconnect with backoff.
  2. Verify authentication/session is still valid before reconnect (an expired session causes immediate re-close loops).
  3. Check server status and network if reconnects cycle rapidly.
Defensive patterns

Strategy: retry

Validate before calling

// close frames cannot be pre-validated; the strategy is reconnect-with-backoff on the Closed event.

Try / catch

// InvokeClosed(ex) is already called; subscribe to connector Closed/IsConnected
// and trigger a reconnect with exponential backoff.

Prevention

When it happens

Trigger: The notifications server sends WebSocketMessageType.Close (clean shutdown), or any code path reaching the Close branch. The exception is caught immediately and passed to InvokeClosed.

Common situations: Server restart/deploy, idle timeout, load-balancer dropping the socket, or the user being logged out. Not necessarily a defect; it is the reconnect signal.

Understand the failure class

Related errors


AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13). Data as JSON: /api/errors/a8ab947d800bb886. Report an issue: GitHub.