Share via

Cannot connect to SignalR service when use yarp in Aspire 13

Hoài Nam Nguyễn 81 Reputation points
2026-03-15T07:38:02.0033333+00:00

I have 2 services: Presence service in program.cs I have:

app.MapHub<PresenseHub>("/hubs/presence");

message service:

app.MapHub<MessageHub>("/hubs/message");

I use Yarp Gateway in Aspire 13:

var gateway = builder.AddYarp("gateway")
    .WithConfiguration(yarp =>
    {
        yarp.AddRoute("/hubs/presence/{**catch-all}", presence);
        yarp.AddRoute("/hubs/message/{**catch-all}", chatMessage);
    })
    .WithEnvironment("ASPNETCORE_URLS", "http://*:8001")
    .WithEndpoint(port: 8001, targetPort: 8001, scheme: "http", name: "gateway", isExternal: true);

at React client:

this.hubConnection = new HubConnectionBuilder()
            .withUrl('http://localhost:8001/hubs/presence', {
                accessTokenFactory: () => {
                    return token
                }
            })
            .withAutomaticReconnect()
            .configureLogging(LogLevel.Information)
            .build();

Screenshot 2026-03-15 142830

When connecting to the hub, I get the error shown in the image. I don't know what I did wrong. Please help me.

Developer technologies | ASP.NET | ASP.NET Core
0 comments No comments

3 answers

Sort by: Most helpful
  1. Danny Nguyen (WICLOUD CORPORATION) 6,615 Reputation points Microsoft External Staff Moderator
    2026-03-16T09:37:55.76+00:00

    Hi @Hoài Nam Nguyễn ,

    This error happens on the SignalR negotiate request:

    POST http://localhost:8001/hubs/presence/negotiate?... net::ERR_EMPTY_RESPONSE

    So the gateway is not returning any HTTP response (wrong route or the proxy can’t forward the request correctly).

    Please check

    1. Verify the YARP route really forwards to the Presence service

    Make sure the gateway route /hubs/presence/{*catch-all} points to the Presence service address + port that is actually listening (the same one you would use if you called Presence directly).

    A fast test:

    • call the Presence service directly: http://<presence-host>:<port>/hubs/presence/negotiate?negotiateVersion=1
    • if that works but through gateway fails, your gateway route/cluster is wrong.
    1. Make sure WebSockets are enabled on the gateway

    SignalR uses WebSockets (or falls back to SSE/LongPolling). If WebSockets aren’t enabled in the proxy host, SignalR often fails.

    If you control the gateway app code, ensure this exists:

    
    app.UseWebSockets();
    
    app.MapReverseProxy();
    
    
    1. If your React app runs in a container: don’t use localhost:8001

    Inside a container, localhost means “this container”, not the gateway container.

    • React on your host browser: http://localhost:8001/... is correct.
    • React in Docker/Aspire: use the gateway DNS name on the internal network (for example http://gateway:8001/... depending on your setup).
    1. If you run multiple instances of the hub service behind YARP / a load balancer. Then you need:
    • sticky sessions (session affinity), or
    • a SignalR backplane / Azure SignalR Service

    Otherwise negotiate may hit instance A, and the actual connection hits instance B.

    I also recommend checking out these docs

    I hope this helps.

    If you found my response helpful or informative, I would greatly appreciate it if you could follow this guidance or provide feedback.

    Thank you. 


  2. Bruce (SqlWork.com) 83,741 Reputation points
    2026-03-15T16:31:54.91+00:00

    If hosted in azure or any load balancer, you must also implement sticky sessions with the yarp connections

    0 comments No comments

  3. Q&A Assist
    2026-03-15T07:38:20.5533333+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    The browser log shows the SignalR client failing on the /negotiate call with net::ERR_EMPTY_RESPONSE, which means the gateway is not returning a valid HTTP response for POST http://localhost:8001/hubs/presence/negotiate?negotiateVersion=1.

    From the provided context, typical causes for SignalR connection failures are:

    1. The SignalR route is not mapped correctly in the server app.
    2. A reverse proxy/firewall is blocking or rewriting the request.
    3. The SignalR middleware (MapSignalR/hub mapping) is not invoked as expected.

    In this setup, the YARP gateway must forward all SignalR traffic, including /negotiate, /connect, /reconnect, and WebSocket/long‑polling requests, to the presence and message services. If the route configuration does not correctly forward /hubs/presence/negotiate, the client will see exactly this negotiation failure.

    Based on the troubleshooting guidance:

    1. Verify that the hub endpoints are reachable directly
      • Run the presence service without YARP and browse to /hubs/presence.
      • For ASP.NET/ASP.NET Core SignalR, the hub proxy or endpoint must be reachable; otherwise errors like $.connection is undefined or 404s occur.
      • Ensure the hub mapping (app.MapHub<PresenseHub>("/hubs/presence");) is executed and the app is listening on the expected port.
    2. Verify that the reverse proxy is not blocking or misrouting the request
      • The context notes that firewalls or proxies that are not configured properly can cause connection failures or 500‑class errors because request headers or paths are rewritten.
      • Ensure the YARP route for /hubs/presence/{**catch-all} forwards to the correct backend cluster/URL where the presence service is running, and that it supports WebSockets and long‑polling.
      • Confirm that the first route in the server app is the SignalR hub route when using traditional routing, as adding routes before the hub route can interfere with SignalR.
    3. Capture and inspect the traffic
      • Use browser network tools or a network trace (for example, Fiddler or the browser’s Network tab) to see what response the gateway returns for /hubs/presence/negotiate.
      • In a working setup, /negotiate should return JSON with a connection ID and available transports. An empty response or connection reset indicates the gateway is not forwarding correctly or the backend is failing before responding.
    4. Check for server‑side errors
      • Inspect the logs of the presence service and the YARP gateway for any exceptions when the /negotiate request arrives.
      • If the backend throws during negotiation, the client will see negotiation failures; server logs will show the root cause.

    Once the YARP route is correctly forwarding /hubs/presence/negotiate to the presence service and the hub endpoint is reachable, the React client configuration shown should be able to complete negotiation and establish the SignalR connection.


    References:

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.