Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Don't log stack traces for localhost bind failures.#1238

Merged
Tratcher merged 1 commit intodevfrom
tratcher/localhostwarn
Nov 29, 2016
Merged

Don't log stack traces for localhost bind failures.#1238
Tratcher merged 1 commit intodevfrom
tratcher/localhostwarn

Conversation

@Tratcher
Copy link
Copy Markdown
Member

#1001
We're getting almost daily hits on this issue. A non-fatal error is being displayed like a fatal error and it distracts users from their real problems. Azure may or may not ever change their implementation.
@muratg @halter73

I also recommend we backport this to 1.0.x and 1.1.x.

Before:

dbug: Microsoft.AspNetCore.Hosting.Internal.WebHost[3]
      Hosting starting
warn: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to bind to http://localhost:19786 on the IPv6 loopback interface.
System.AggregateException: One or more errors occurred. ---> Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4089 EAFNOSUPPORT address family not supported
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.tcp_bind(UvTcpHandle handle, SockAddr& addr, Int32 flags) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Networking\Libuv.cs:line 202
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvTcpHandle.Bind(ServerAddress address) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Networking\UvTcpHandle.cs:line 48
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.TcpListenerPrimary.CreateListenSocket() in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Http\TcpListenerPrimary.cs:line 39
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Listener.<StartAsync>b__8_0(Object state) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Http\Listener.cs:line 39
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.ListenerPrimary.<StartAsync>d__12.MoveNext() in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Http\ListenerPrimary.cs:line 54
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.KestrelEngine.CreateServer(ServerAddress address) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\KestrelEngine.cs:line 118
   at Microsoft.AspNetCore.Server.Kestrel.KestrelServer.Start[TContext](IHttpApplication`1 application) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\KestrelServer.cs:line 168
---> (Inner Exception #0) Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException: Error -4089 EAFNOSUPPORT address family not supported
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.Libuv.tcp_bind(UvTcpHandle handle, SockAddr& addr, Int32 flags) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Networking\Libuv.cs:line 202
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvTcpHandle.Bind(ServerAddress address) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Networking\UvTcpHandle.cs:line 48
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.TcpListenerPrimary.CreateListenSocket() in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Http\TcpListenerPrimary.cs:line 39
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.Listener.<StartAsync>b__8_0(Object state) in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Http\Listener.cs:line 39
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Server.Kestrel.Internal.Http.ListenerPrimary.<StartAsync>d__12.MoveNext() in C:\git\Universe\KestrelHttpServer\src\Microsoft.AspNetCore.Server.Kestrel\Internal\Http\ListenerPrimary.cs:line 54<---

dbug: Microsoft.AspNetCore.Hosting.Internal.WebHost[4]
      Hosting started
Hosting environment: Production
Content root path: D:\home\site\wwwroot\
Now listening on: http://localhost:19786
Application started. Press Ctrl+C to shut down.

After:

dbug: Microsoft.AspNetCore.Hosting.Internal.WebHost[3]
      Hosting starting
info: Microsoft.AspNetCore.Server.Kestrel[0]
      Unable to bind to http://localhost:20266 on the IPv6 loopback interface.
dbug: Microsoft.AspNetCore.Hosting.Internal.WebHost[4]
      Hosting started
Hosting environment: Production
Content root path: D:\home\site\wwwroot\
Now listening on: http://localhost:20266
Application started. Press Ctrl+C to shut down.

We could add an additional log for real fatal errors on line 185.

@Tratcher Tratcher added this to the 1.2.0 milestone Nov 28, 2016
@Tratcher Tratcher self-assigned this Nov 28, 2016
else
{
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface.");
_logger.LogInformation(0, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface.");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should still be a warning - just don't pass the exception to the log call.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warnings should be actionable, this isn't. I'm tempted to downgrade it to debug.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning could very well be actionable if you're not running in a shared hosting environment.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does shared hosting make the error any different? It's fatal or it isn't.
Yes we know Azure has one specific issue, but overall we've decided that only failing on one protocol isn't fatal.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because if you have full control over the host, you could see why binding to either IPv4 or IPv6 failed and then fix it. Typically it's some OS-level configuration, no?

You could also change "localhost" to "127.0.01" or "[::1]" in UseUrls() if you expect to only bind to one interface.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on the error. What errors have you seen that we may be hiding here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The -4089 EAFNOSUPPORT error.

}
else
{
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv6 loopback interface.");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the error isn't -4089 EAFNOSUPPORT? Should we special case just that error code and log the exception otherwise? If it is something else, it would be good to know.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could include the error code. We don't need the stack trace regardless.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was thinking about that too. We know it's a benign error specifically on Azure, but it's still a potentially legit error in other environments.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the scariest part of the log message is the stack trace. How about logging the exception message only?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And UvException.Message. That would leave out the stack trace. Sometimes libuv uses different error codes on different platforms, so having the message could be useful.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the StatusCode is in the Message, no need to duplicate.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unable to bind to http://localhost:27574 on the IPv6 loopback interface. (Error -4089 EAFNOSUPPORT address family not supported)

@halter73
Copy link
Copy Markdown
Member

LGTM after it's changed back to a warning. If there was an easy way to force an EAFNOSUPPORT error, I would ask for a test, but I think that's more complicated than it's worth.

catch (AggregateException ex) when (ex.InnerException is UvException)
{
if ((ex.InnerException as UvException).StatusCode == Constants.EADDRINUSE)
var uvEx = (UvException)ex.InnerException;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use as

{
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface.");
exceptions.Add(ex.InnerException);
_logger.LogInformation(0, $"Unable to bind to {parsedAddress.ToString()} on the IPv4 loopback interface. ({uvEx.Message})");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to ...interface: ({uvEx.Message}) (i.e. colon instead of period)

{
_logger.LogWarning(0, ex, $"Unable to bind to {parsedAddress.ToString()} on the IPv6 loopback interface.");
exceptions.Add(ex.InnerException);
_logger.LogInformation(0, $"Unable to bind to {parsedAddress.ToString()} on the IPv6 loopback interface. ({uvEx.Message})");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to ...interface: ({uvEx.Message}) (i.e. colon instead of period)

catch (AggregateException ex) when (ex.InnerException is UvException)
{
if ((ex.InnerException as UvException).StatusCode == Constants.EADDRINUSE)
var uvEx = (UvException)ex.InnerException;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use as

@Tratcher Tratcher force-pushed the tratcher/localhostwarn branch from 6c9e55c to a82270e Compare November 29, 2016 00:33
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants