RDP, An existing connection was forcibly closed by the remote host

PatrickZ
PatrickZ Explorer

Hello,
I have an RDP (RDPv1) based C# (LSEG.Data v. 2.1.0) application that randomly gets "existing connection was forcibly closed by the remote host" on endpoint requests (like Fundamentals, but not exclusively). See the attached trace in the 2 small extraction files.

1. What is a possible cause of this?
2. Why the session event handlers do not work on "forcibly closed"?
The session is obtained through:
return PlatformSession.Definition(SessionName).AppKey(credentials_?.RDPAppKey)
.OAuthGrantType(new GrantPassword().UserName(credentials_?.RDPUser)
.Password(credentials_?.RDPPassword))
.TakeSignonControl(TakeExclusiveSignonControl.GetValueOrDefault())
.GetSession().OnState((state, msg, s) => SessionStateChanged(state, msg, s))
.OnEvent((eventCode, msg, s) => SessionEventReceived(eventCode, msg, s));

where TakeExclusiveSignonControl is usually False,

As seen, I have the OnState() and OnEvent() handlers installed, but they are not called
when "existing connection was forcibly closed by the remote host" happen.
How to intercept this event when the normal session event handlers do not work?

Thanks
P.Zalewski

Answers

  • Hello @PatrickZ

    The error message "existing connection was forcibly closed by the remote host" indicates that the connection was cut by the server side.

    Could you please enable the library log as follows?

    Log.Level = NLog.LogLevel.Debug;

    By the way, can the application re-request data after got this exception (you may need to catch it in the code)?

  • Hello
    Thank you for your answer.

    Well, it is obvious that the connection was reset by the server application. This implies the following questions:
    1. Why or in which circumstances this can happen. I can provide the credentials (Machine ID) used by our application at the client site, as well as the timestamps of the events.

    2. Why this kind of event is not handled through the LSEG.Data.Core.ISession through the callbacks like OnState() or OnEvent() ? The client application should have a chance to intercept the change of session status and be able to renew the connection. It seems that after "An existing connection was forcibly closed by the remote host" exception the session state is still Opened, while the connection is in reality broken.

    3. It is not really possible to catch the exception because it can happen anywhere, so it can be caught in the application Main() which, in the case of the event driven applications, does not have the access to the Session reference. In our case, it is a "plugin" based application, where the real-time instantiation of the particular plugin causes the instantiation of the ISession. The main program does not nor should not have the access to it.

    4. Enabling the library log is not an option: I cannot enable such an extended logging on the production site which thousands of securities being requested. It would degrade the performance and fill the rotating logs with such a speed that nobody would be able to collect them before the previous info is overridden.

    5. Since the usual callback does not seem to work, what is the strategy the you propose to handle this event?
    For me it is obvious, that server application should never just cut the connection.

    6. How should I proceed with this issue? Should I report it through the LSEG Support? This is an important issue that should be handled at the library side.

    Thanks

    Patrick Z

  • Jirapongse
    Jirapongse ✭✭✭✭✭

    @PatrickZ

    1. We don't have permission to access to server to verify the connection. You need to contact the product support team directly via LSEG support to verify this. Please include the URL of this discussion in your raised question to prevent it from being redirected back to this Q&A forum. Moreover, if you have firewall or proxy servers, you may need to contact your IT support team to verify if the disconnection is from the firewall or proxy servers
    2. Under the hood, the library communicates via REST APIs using HTTP requests and responses, making it inherently stateless. A session within the library is represented by a session token. Upon startup, the library requests a token from the Data Platform's authentication service. As long as the token remains valid, it can be used to initiate new connections and retrieve data—effectively indicating that the session is still active.

      I tested this behavior by disabling the network after the session was opened. As a result, the library was unable to refresh the token once it expired. In this scenario, the session state transitioned to Pending because the session token was no longer valid.

      image.png

    3. I checked and found that the application can use the try/catch block to catch this disconnection exception. You need to use the try/catch block when using the EndpointRequest. For example:

                using ISession session = Configuration.Sessions.GetSession(Configuration.Sessions.SessionTypeEnum.RDPv1);

    // Open the session
    session.Open();

    try
    {

    var datagrid_endpoint = EndpointRequest.Definition( "/data/datagrid/beta1/").Method(EndpointRequest.Method.POST);


    var request1 = new JObject()
    {


    };

    var response = await datagrid_endpoint.BodyParameters(request1).GetDataAsync();
    Console.WriteLine(response.Data.Raw.ToString());


    }
    catch (Exception e)
    {
    Console.WriteLine($"\n#### Exception **************\nFailed to execute.");
    Console.WriteLine($"Exception: {e.GetType().Name} {e.Message}");
    if (e.InnerException is not null) Console.WriteLine(e.InnerException);
    Console.WriteLine("***************");
    }
  • I read your comment a little perplexed.

    1. If I understand well, after the socket connection is reset ("existing connection was forcibly closed by the remote host") by the server, the client application, as long as the token is valid, so up to 600 seconds (!), can still request and receive the data!

    This seems to (at least partially) confirmed by the logs I received, because after the connection was reset, I still see plenty of request/response activity. The reset was at ~2025-08-25 13:14:19 local time, and I see the activity until ~2025-08-25 13:18:21. Unfortunately, the log I received ends at this moment, because the person that extracted it did not wait any longer…

    So, am I correct assuming that for about 6 more minutes everything would go smoothly and then the library would issue another token refresh request, but NOT because the connection was broken, but because the ...token has expired?

    If so, is it necessary to do anything in this case about the connection reset? At the next round (our application is a scheduler based) of requests, the application would request the new token anyways and the things would continue as usual. Please confirm!

    2. If the catching would be required (I already have a try/catch at the higher level (but obviously below the Main program level), well, I wonder if it would be even a good idea, since there is a problem with identifying the kind of exception. There is no specific exception type, nor a particular error code and we cannot arbitrarily decide that it is the connection reset.

    3. I still think that the Session class should own the socket and catching any socket exception in the Session class would enable it the change of the session status and therefore use the callbacks to communicate "normally" with the client application

    4. What are the potential reasons for the server to reset the connection? Possibly a slow consumer? Is there anything recommended to do at the client level to avoid this kind of problems?

    Thanks

    P. Zalewski

  • Jirapongse
    Jirapongse ✭✭✭✭✭
    1. According to my test, as long as the session is still open, the application can use it to retrieve data
    2. The exception that I got when I cut the connection is HttpRequestException
    3. You need to contact the server team to verify the server log or contact your IT support to verify the network settings
  • PatrickZ
    PatrickZ Explorer
    edited September 26

    Thanks for your answer.

    regarding the session state. You confirm that that while the session is still Opened, the application can request the data. The problem is that the transition of the session state is unclear and there seem not to be any documentation regarding it.
    The situation that we face is, I repeat, "existing connection was forcibly closed by the remote host", This is particularly with the subscription (by subscription I mean using the PricingStream and adding the RICs to the stream to receive the updates). The only thing to simulate the situation is to cut the network. After I do this, I observed, that the session state remains Opened for the time remaining form the cut off time up to the 600 seconds period, i.e. until I receive TokenRefreshFailed event. Then the session state becomes Pending.
    Reconnecting the network after a certain time, generally brings a pretty strange cascade of events:
    -StreamConnected
    -StreamAuthenticationFailed
    -StreamDisconnected
    -StreamConnected
    -StreamAuthenticationSuccess
    followed by the session state becoming Opened

    Re-establishing the network, even after a longer time period, like 15 minutes always makes the session pass from Pending to Opened.
    In other words, on the client side I never been able to provoke the situation when the session state would become Closed.

    Now, from the server side, I wonder whether:
    1. if the server side cuts/resets the connection (at the socket level), what will be the state of the session? Pending or Closed?
    2. Can the session become Closed because of the events on the server side?
    3. if the server side cuts resets the connection, is the instance of my ISession still "good" in the sense that I do not need to call again IPlatformSessionDefinition.GetSession()?
    4. Once I have the instance of ISession, can I indefinitely change the state from Close to Open and then again close it and reopen as many times that I want without calling GetSession() for the same credentials)?
    In other words, in normal circumstances, an application should call GetSession() only once and, depending on the needs just Open/Close it indefinitely?
    5. Can you provide any document that describes the Session's state transitions?

    Thanks

  • Jirapongse
    Jirapongse ✭✭✭✭✭

    Under the hood, the library communicates with the Data Platform via REST APIs using HTTP requests and responses, making it inherently stateless.

    A session within the library is represented by a session token, which is requested from the platform’s authentication service during startup. As long as the token remains valid, it can be used to initiate new connections and retrieve data—indicating that the session is active. Importantly, the session token is not directly tied to connection resets.

    Session tokens expire after 10 minutes, so the library must refresh them periodically. If the token refresh process fails, the session transitions to a Pending state and continues retrying. Once a new token is successfully obtained, the session returns to the Opened state.

    The session is explicitly closed when the application calls the session.close() method.

  • PatrickZ
    PatrickZ Explorer
    edited September 26

    Thank you for your answer and a high level description of how the session behaves.
    I need the answer to some more detailed questions:
    1. Can ever the session become Closed because of the events/actions on the server side?

    2. Once the session instance is retrieved using IPlatformSessionDefinition.GetSession() (for example at the application startup), are there any circumstances to call the GetSession() again (assuming the user credentials did not change)?

    3. Once ISession is closed explicitly, can it be opened again or the proper way of action is to dispose of the instance and call GetSession() and open the new instance?

    4. Also, regarding my original question about the server side socket reset and your advice to

    "You need to use the try/catch block when using the EndpointRequest"

    When this happens, (besides catching the exception so it does not propagate) is there any specific action to be done in the catch to handle this? Is it guaranteed that on the client side the session will become first Pending and then, after the socket is reestablished, it will be Opened again?

    4. Is there any documentation available regarding the session?

    Thank you

  • Hello again!
    As explained I try simulating the web socket failure by cutting the network access. When done, the session stat would be Pending trying then to reestablish the connection every 15 seconds. After restoring the network access, ISession would recover by first passing the status from Pending to Open and then (if the token expired) by sending Password Grant Refresh request. Until today, it always worked, but today I found another condition: the RDP access token refresh failed with the Status:
    Status response: {
    "ID": 1,
    "Type": "Status",
    "Domain": "Login",
    "Key": {
    "NameType": 5,
    "Elements": {
    "AuthenticationErrorCode": 1026,
    "AuthenticationErrorText": "Request for token validation failed:Authentication server did not contain "active" in response"
    }
    },
    "State": {
    "Stream": "Closed",
    "Data": "Suspect",
    "Code": "UserAccessToAppDenied",
    "Text": "Authentication failed (1026, Request for token validation failed:Authentication server did not contain "active" in response)."
    }
    }
    It looks like that server got rid of my session info. Following this, my application had to wait for another 10 minutes (600s) to issue another Password Grant Refresh, which was, this time successful.

    QUESTION: what is the recommended course of action in this case? My application cannot wait 10 minutes to have another token refresh. Should I (after intercepting UserAccessToAppDenied status), close the existing session, dispose of it and call again?Please look into this case, since it is important.

    I have the impression that you respond only with the optimistic scenarios, however the reality is that things can go other way. Also, there are the previous questions that I reposted earlier today.
    Please, see the attached log file for the details. The is at time stamp of reception of "UserAccessToAppDenied" status 2025-09-26 16:00:14,034 (line 92)

    Thank you