stride3d/stride · error · SimpleSocketException

Invalid ack

Error message

Invalid ack

What it means

SimpleSocket.SendAndReceiveAck writes an acknowledgement value and expects the remote side to echo the exact expected ack; any mismatch throws SimpleSocketException("Invalid ack"). It is a handshake integrity check on both server and client startup.

Solutions

  1. Ensure client and server use the same SimpleSocket protocol/version.
  2. Verify the port actually hosts the expected socket service.
  3. Check for concurrent handshakes racing on the same socket; serialize the connection setup.
  4. Log both sentAck and received ack values to diagnose the mismatch.

Example fix

// before
var client = SimpleSocket.StartClient(port); // version mismatch with server
// after
// align both processes to the same Stride Network package version, then
var client = SimpleSocket.StartClient(port);
Defensive patterns

Strategy: try-catch

Try / catch

try { var client = SimpleSocket.StartClient(port); }
catch (SimpleSocketException e) when (e.Message == "Invalid ack") { /* version/port mismatch: alert ops */ }

Prevention

When it happens

Trigger: StartServer/StartClient handshake where the peer returns an ack value different from the expected one — wrong protocol version, desynchronized stream, or a non-Stride service on the port.

Common situations: Client and server running mismatched library versions with different handshake formats; connecting to a wrong port where another service responds; packet interleaving from a race in connection setup.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/aa00668c8ccb3bf0. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Engine/Engine/Network/SimpleSocket.cs:140

                Connected?.Invoke(this);

                isConnected = true;
            }
            catch (Exception)
            {
                DisposeSocket();
                throw;
            }
        }

        private static async Task SendAndReceiveAck(TcpSocketClient socket, uint sentAck, uint expectedAck)
        {
            await socket.WriteStream.WriteInt32Async((int)sentAck).ConfigureAwait(false);
            await socket.WriteStream.FlushAsync().ConfigureAwait(false);
            var ack = (uint)await socket.ReadStream.ReadInt32Async().ConfigureAwait(false);
            if (ack != expectedAck)
                throw new SimpleSocketException("Invalid ack");
        }

        private void SetSocket(TcpSocketClient socket)
        {
            this.socket = socket;
        }

        private void DisposeSocket()
        {
            if (this.socket != null)
            {
                if (isConnected)
                {
                    isConnected = false;
                    Disconnected?.Invoke(this);
                }

                this.socket.Dispose();

View on GitHub (pinned to 96fad776d2)