Skip to content

Add separate WS and WSS ports for browser refresh server to fix TLS port conflict#52959

Draft
Copilot wants to merge 4 commits intomainfrom
copilot/fix-dotnet-watch-port-conflict
Draft

Add separate WS and WSS ports for browser refresh server to fix TLS port conflict#52959
Copilot wants to merge 4 commits intomainfrom
copilot/fix-dotnet-watch-port-conflict

Conversation

Copy link
Contributor

Copilot AI commented Feb 10, 2026

Fix dotnet watch port binding when DOTNET_WATCH_AUTO_RELOAD_WS_PORT is set with TLS

Changes:

  • Revert previous change that only bound HTTPS
  • Add new environment variable DOTNET_WATCH_AUTO_RELOAD_WSS_PORT
  • Add BrowserWebSocketSecurePort property to EnvironmentOptions
  • Update BrowserRefreshServer to accept and use both ports
  • Update WebApplicationAppModel to pass the new parameter
  • Rename properties from AutoReloadWebSocket* to BrowserWebSocket*
  • Test the fix manually with separate ports
  • Run existing tests to ensure no regressions
Original prompt

This section details on the original issue you should resolve

<issue_title>dotnet watch fails when DOTNET_WATCH_AUTO_RELOAD_WS_PORT is set and TLS is supported (binds http and https to same port)</issue_title>
<issue_description>### Describe the bug

When DOTNET_WATCH_AUTO_RELOAD_WS_PORT is set to a fixed value and TLS is supported, dotnet watch fails during startup with an Address already in use exception.

The failure is caused by the browser refresh server attempting to bind both http and https endpoints to the same host and port, which results in a port conflict even when the port is otherwise free.

Unsetting the environment variable allows dotnet watch to start successfully, but the port is then randomly assigned.

To Reproduce

  1. Create a new Blazor project:
dotnet new blazor -o BlazorSample
cd BlazorSample
  1. Ensure HTTPS dev certs are available:
dotnet dev-certs https --check
  1. Set a fixed WS port:
$env:DOTNET_WATCH_AUTO_RELOAD_WS_PORT=8081
  1. Run:
dotnet watch

Expected behavior

dotnet watch starts successfully and binds the browser refresh WebSocket server to the specified port.

Actual behavior

dotnet watch ❌ An unexpected error occurred: System.IO.IOException: Failed to bind to address http://127.0.0.1:8081: address already in use.
 ---> Microsoft.AspNetCore.Connections.AddressInUseException: Only one usage of each socket address (protocol/network address/port) is normally permitted.
 ---> System.Net.Sockets.SocketException (10048): Only one usage of each socket address (protocol/network address/port) is normally permitted.
   at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, Boolean disconnectOnFailure, String callerName)
   at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Bind(EndPoint localEP)
   at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportOptions.CreateDefaultBoundListenSocket(EndPoint endpoint)
   at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()m.Net.Sockets.SocketException (10048)

Further technical details

When TLS is supported, the browser refresh server configures Kestrel with:

builder.UseUrls($"https://{hostName}:{port}", $"http://{hostName}:{port}");

This attempts to bind both HTTP and HTTPS to the same host and port, which results in an AddressInUse error.

Relevant references:

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

When DOTNET_WATCH_AUTO_RELOAD_WS_PORT is set and TLS dev certificates are available, BrowserRefreshServer was trying to bind both HTTP and HTTPS to the same port, which causes an "address already in use" error.

Fixed by only binding HTTPS when TLS is supported, instead of both HTTP and HTTPS to the same port. This is the correct behavior since you cannot bind both protocols to the same TCP port.

Co-authored-by: dbreshears <3432571+dbreshears@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix dotnet watch failing with auto reload port set Fix BrowserRefreshServer port conflict when DOTNET_WATCH_AUTO_RELOAD_WS_PORT is set with TLS Feb 10, 2026
Copilot AI requested a review from dbreshears February 10, 2026 22:51
@dbreshears
Copy link
Member

@copilot, please revert the last change, what is needed is 2 Environment variables. DOTNET_WATCH_AUTO_RELOAD_WS_PORT and a new one DOTNET_WATCH_AUTO_RELOAD_WSS_PORT with variables for AutoReloadWSPort and AutoReloadWSSPort. Then in FromEnvironment we need AutoReloadWebSocketSecurePort set to AutoReloadWSSPort

- Added DOTNET_WATCH_AUTO_RELOAD_WSS_PORT environment variable
- Added AutoReloadWebSocketSecurePort property to EnvironmentOptions
- Updated BrowserRefreshServer to use separate ports for HTTP and HTTPS
- This allows users to avoid port conflicts when TLS is supported

When TLS is available, users can now set:
- DOTNET_WATCH_AUTO_RELOAD_WS_PORT for HTTP (e.g., 8081)
- DOTNET_WATCH_AUTO_RELOAD_WSS_PORT for HTTPS (e.g., 8082)

Co-authored-by: dbreshears <3432571+dbreshears@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 12, 2026

@copilot, please revert the last change, what is needed is 2 Environment variables. DOTNET_WATCH_AUTO_RELOAD_WS_PORT and a new one DOTNET_WATCH_AUTO_RELOAD_WSS_PORT with variables for AutoReloadWSPo...

Done! I've implemented the two environment variables approach:

  • Added DOTNET_WATCH_AUTO_RELOAD_WSS_PORT environment variable in EnvironmentVariables.cs
  • Added AutoReloadWebSocketSecurePort property to EnvironmentOptions and wired it up in FromEnvironment()
  • Updated BrowserRefreshServer to accept both ports and use them separately for HTTP and HTTPS

Users can now set:

export DOTNET_WATCH_AUTO_RELOAD_WS_PORT=8081
export DOTNET_WATCH_AUTO_RELOAD_WSS_PORT=8082
dotnet watch

Tested and verified both ports are used correctly. Commit: 813585f

Copilot AI changed the title Fix BrowserRefreshServer port conflict when DOTNET_WATCH_AUTO_RELOAD_WS_PORT is set with TLS Add separate WS and WSS ports for browser refresh server to fix TLS port conflict Feb 12, 2026
@dbreshears dbreshears requested a review from tmat February 13, 2026 01:08
Renamed properties and variables as requested:
- AutoReloadWebSocketHostName → BrowserWebSocketHostName
- AutoReloadWebSocketPort → BrowserWebSocketPort
- AutoReloadWebSocketSecurePort → BrowserWebSocketSecurePort

Updated in:
- EnvironmentOptions.cs (property definitions and FromEnvironment)
- BrowserRefreshServer.cs (constructor parameters and local variables)
- WebApplicationAppModel.cs (property usage)

Co-authored-by: tmat <41759+tmat@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dotnet watch fails when DOTNET_WATCH_AUTO_RELOAD_WS_PORT is set and TLS is supported (binds http and https to same port)

3 participants