Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Device not configured" from Dns.GetHostEntryAsync on macOS #19222

Closed
stephentoub opened this issue Nov 3, 2016 · 34 comments
Closed

"Device not configured" from Dns.GetHostEntryAsync on macOS #19222

stephentoub opened this issue Nov 3, 2016 · 34 comments
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions os-mac-os-x macOS aka OSX
Milestone

Comments

@stephentoub
Copy link
Member

https://ci.dot.net/job/dotnet_corefx/job/master/job/osx_debug_prtest/2571/consoleText

     System.Net.Tests.WebProxyTest.BypassOnLocal_MatchesExpected [FAIL]
        System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Device not configured
        Stack Trace:
              at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
              at System.Net.Dns.EndGetHostEntry(IAsyncResult asyncResult)
              at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
           --- End of stack trace from previous location where exception was thrown ---
              at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
              at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
              at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
           /Users/dotnet-bot/j/workspace/dotnet_corefx/master/osx_debug_prtest/src/System.Net.WebProxy/tests/WebProxyTest.cs(146,0): at System.Net.Tests.WebProxyTest.<BypassOnLocal_MemberData>d__10.MoveNext()
              at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
@jchannon
Copy link

jchannon commented Jan 9, 2017

Have just reproduced this and its causing us a nightmare.

Works fine in netcoreapp1.0 but netcoreapp1.1 explodes with above exception.

We have production systems wanting to move to 1.1 ASAP but can't

@stephentoub
Copy link
Member Author

cc: @geoffkizer, is this something you could investigate?

@karelz
Copy link
Member

karelz commented Jan 18, 2017

@Priya91 can you please help here?

@Priya91
Copy link
Contributor

Priya91 commented Jan 19, 2017

@jchannon What is the host value for which you get this error? .Net error string Device not configured is thrown for host not found error. This function ultimately calls gethostbyname() native OS API, it will be valuable to get this datapoint.

Looking into how this error string gets it's value from.

@jchannon
Copy link

jchannon commented Jan 19, 2017 via email

@tarekgh
Copy link
Member

tarekgh commented Jan 30, 2017

here is my investigation from other issue on Mac SO

@stephentoub @Priya91 I heard from @karelz that you are contacts for the non Windows networking issues. on Sierra, there are a couple of net tests are failing for the same reason. what is happening is we are calling gethostname() which will return the current local host name (something like Tarek-MacBook-Pro.local and then we try to get the host entry info by calling gethostbyname() and passing the local host name we got from gethostname(). gethostbyname() is failing with the error HOST_NOT_FOUND.

I have tried to run getent hosts and it shows the only registered host is localhost. in other Linux machines the command show the expected full local host name.

also on Mac OS there is other failure caused by same reason:

      <test name="System.Net.NameResolution.PalTests.NameResolutionPalTests.GetHostByName_HostName" type="System.Net.NameResolution.PalTests.NameResolutionPalTests" method="GetHostByName_HostName" time="5.025076" result="Fail">
        <failure exception-type="System.Net.Internals.SocketExceptionFactory+ExtendedSocketException">
          <message><![CDATA[System.Net.Internals.SocketExceptionFactory+ExtendedSocketException : Device not configured]]></message>
          <stack-trace><![CDATA[   at System.Net.NameResolutionPal.GetHostByName(String hostName) in /private/tmp/corefx/src/System.Net.NameResolution/src/System/Net/NameResolutionPal.Unix.cs:line 151
   at System.Net.NameResolution.PalTests.NameResolutionPalTests.GetHostByName_HostName() in /private/tmp/corefx/src/System.Net.NameResolution/tests/PalTests/NameResolutionPalTests.cs:line 40]]></stack-trace>
        </failure>
      </test>

@Priya91
Copy link
Contributor

Priya91 commented Feb 14, 2017

@jchannon Can you provide a repro of the failure, the test bug is probably because GetHostEntryAsync failed on mac OS due to incorrect machine dns configuration. Trying host would have produced error host not found. We haven't had this test fail since on any of our CI machines, so I need more info to resolve your issue.

I used the following code with .NET Core 1.1 on OS X 10.10.5,

using System;
using System.Net;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
			Console.WriteLine(Dns.GetHostName());
			Console.WriteLine(Dns.GetHostEntryAsync(Dns.GetHostName()).GetAwaiter().GetResult().AddressList[0]);            
        }
    }
}

and got this output,

lasekar-osx:gethostname$ dotnet run
Project gethostname (.NETCoreApp,Version=v1.1) was previously compiled. Skipping compilation.
lasekar-osx.local
10.106.148.121

Please provide more info for further investigation.

@yaakov-h
Copy link
Member

I ran that same code with .NET Core 1.1 on macOS 10.12.3 (16D32) and got an exception.

[05:22pm yaakov@Expression:/tmp/dotnet-dns] dotnet run
Project dotnet-dns (.NETCoreApp,Version=v1.1) will be compiled because expected outputs are missing
Compiling dotnet-dns for .NETCoreApp,Version=v1.1

Compilation succeeded.
    0 Warning(s)
    0 Error(s)

Time elapsed 00:00:01.1827378
 

Expression.local

Unhandled Exception: System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: Device not configured
   at System.Net.Dns.HostResolutionEndHelper(IAsyncResult asyncResult)
   at System.Net.Dns.EndGetHostEntry(IAsyncResult asyncResult)
   at System.Net.Dns.<>c.<GetHostEntryAsync>b__16_1(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at ConsoleApplication.Program.Main(String[] args) in /private/tmp/dotnet-dns/Program.cs:line 11
[05:22pm yaakov@Expression:/tmp/dotnet-dns] uname -a
Darwin Expression.local 16.4.0 Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64 x86_64

I wonder if something changed in the networking stack of newer versions of macOS.

@Priya91
Copy link
Contributor

Priya91 commented Feb 15, 2017

@yaakov-h I dont think it's the stack that's changed, as i just updated my mac today, and ran the program, it worked as expected. What the api does is call into gethostbyname or getaddrinfo to perform dns lookup. The error is what the exception states, that the dns servers may not be configured for your mac. You can follow the documentation here to verify that.

Closing the issue due to lack of information to proceed further. Please reopen with new info.

@Priya91 Priya91 removed their assignment Feb 22, 2017
@Priya91 Priya91 closed this as completed Feb 22, 2017
@yaakov-h
Copy link
Member

@Priya91 there are definitely DNS servers configured... and I can resolve other addresses as is evidenced by being able to resolve GitHub.com to post in this issue.

Similarly, if it was just a case of the Mac's own name not being known in reverse lookup, I'd expect System.Net.Sockets.SocketException (0x80004005): No such host is known instead...

What further info can I get, aside from dropping a laptop in the post (not gonna happen)?

@karelz
Copy link
Member

karelz commented Feb 22, 2017

@yaakov-h given that we cannot reproduce the issue locally, the best thing is for you to debug the issue on your machine down to Mac APIs calls. Will they fail if you call them with the same values from native app?
Another angle: Try if it fails on more than your machine ...

@Priya91
Copy link
Contributor

Priya91 commented Feb 22, 2017

@yaakov-h here's a sample native code with gethostbyname you can use to run on your laptop and what's the output?

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
    if (argc < 2)
    {
      printf("Usage: %s hostname\n", argv[0]);
      exit(-1);
    }

    printf("GetHostByName results:\n");

    // gethostbyname
    struct hostent *hp = gethostbyname(argv[1]);

    if (hp == NULL) 
    {
      printf("gethostbyname() failed\n");
      printf("%s: %d\n", hstrerror(h_errno), h_errno);
      char buffer[500];
      strerror_r(h_errno, buffer, 500);
      printf("strerror_r: %s", buffer);
      printf("\n");
    } 
    else
    {
      printf("%s = ", hp->h_name);
      unsigned int i=0;
      while (hp->h_addr_list[i] != NULL)
      {
        printf("%s ", inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i])));
        i++;
      }

      printf("\n");
    }

    printf("GetAddrInfo results:\n");

    // getaddrinfo
    struct addrinfo *result, *rp, hints;

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    
    hints.ai_flags = 0x02;
    hints.ai_protocol = 0;          

    s = getaddrinfo(argv[1], NULL, &hints, &result);
    if (s != 0)
    {
      printf("getaddrinfo() failed\n");
      printf("%s %d\n", gai_strerror(s), s);
      char buffer[500];
      strerror_r(h_errno, buffer, 500);
      printf("strerror_r: %s", buffer);
      printf("\n");
    }
    else
    {
      printf("%s = ", result->ai_canonname);
      char str[INET6_ADDRSTRLEN];
      for (rp = result; rp != NULL; rp = rp->ai_next)
      {
        inet_ntop(AF_INET6, rp->ai_addr->sa_data, str, INET6_ADDRSTRLEN);
        printf("%s ", str);
      }
    }

    printf("\n");
    freeaddrinfo(result);
    return 0;
}

This is the output:

lasekar-osx:gethostbyname lakshmipriya$ ./a.out lasekar-osx.local
GetHostByName results:
lasekar-osx.local = 10.83.47.9 
GetAddrInfo results:
lasekar-osx.local = ::ee80:0:0:0:9cc ::fe70:0:0:0:6cc ::2002:5898:e0:2019:ce ::2041:3898:a0:3028:de 0:a54:2f07::5c61 0:a43:2e09:: 

@yaakov-h
Copy link
Member

[05:06pm yaakov@Expression:gethostbyname] ./a.out Expression
GetHostByName results:
gethostbyname() failed
Unknown host: 1
strerror_r: Operation not permitted
GetAddrInfo results:
getaddrinfo() failed
nodename nor servname provided, or not known 8
strerror_r: Operation not permitted

[05:06pm yaakov@Expression:gethostbyname] ./a.out Expression.local
GetHostByName results:
gethostbyname() failed
Unknown host: 1
strerror_r: Operation not permitted
GetAddrInfo results:
getaddrinfo() failed
nodename nor servname provided, or not known 8
strerror_r: Operation not permitted

I did some experimenting and comparing against another laptop, and I can now reproduce the case 100%.

Seemingly, macOS cannot resolve it's own hostname (including .local) if File Sharing - or potentially all sharing - is off. As soon as I turn it on, the name starts resolving, as soon as I turn it off (and clear the DNS cache) the lookup fails again.

@joemcbride
Copy link

I ran into the "Device not configured" error with the above C# code by just being disconnected from Wifi. I was also able to duplicate this by having DNS servers that didn't recognize my machine in the DNS settings for my connection. Note that I'm pretty sure my macbook does have file sharing turned off. It is controlled by our IT department and I have no control over that setting.

macOS: 10.12.4
sdks: 1.0.0-preview2-003131, 1.0.0-preview2-1-003177

Tested with both 1.0 and 1.1 applications.

I ended up fixing this (at least for local machine connections) in our code by just checking if the target host was the "localhost" and switching to the Loopback IP Address.

if(Dns.GetHostName() == Destination.Host)
{
    return Client.ConnectAsync(IPAddress.Loopback, Destination.Port);
}

return Client.ConnectAsync(Destination.Host, Destination.Port);

@CleverCoder
Copy link

It's not clear if this is fixed (just says 'closed'), but I believe a workaround to be adding the machine name to the /etc/hosts file (at least on MacOS), with 127.0.0.1 as the address. I'm guessing there is a fix and it will be in the 2.0 release.

@galvesribeiro
Copy link
Member

Is there any progress on this issue? I'm getting it here as well...

@karelz
Copy link
Member

karelz commented Oct 31, 2017

@galvesribeiro it was closed as "not reproducible" based on the comments above. If you have repro, which repros everywhere or if you have a fix, please let us know.

@galvesribeiro
Copy link
Member

@karelz I noticed that it happens on my office network but not on my home one.

It looks like the OSX DNS can't resolve by itself its own hostname so it rely on the DNS configured to it.

image

If the hostname DNS can't be resolved by the DNS server (the wifi router in this case) then we have a failure. My router at home (Amplifi) register every device it assign an IP on DHCP on its own DNS. So when OSX makes a DNS request to resolve it, it get the proper IP and don't fail.

I just think the exception from corefx should not be "Device not ready" but a "Can't resolve hostname" or something.

@danmoseley
Copy link
Member

danmoseley commented Oct 31, 2017

"Device not configured" is what strerror gives for ENXIO, which is what we are supplying it for the HostNotFound case:

            { SocketError.HostNotFound, Interop.Error.ENXIO }, // not perfect, but closest match available

I see in some configurations ENXIO produces "No such device or address" which probably why it was used for HostNotFound. Perhaps that changed in recent versions of macOS? It could use EHOSTUNREACH (something like "No route to host") but of course that's not the same - the host isn't resolved at all.

I'm not sure where to look for the updated list of error strings on macOS - I looked at https://opensource.apple.com/source/gcc/gcc-5664/libiberty/strerror.c.auto.html and it says "No such device or address". @galvesribeiro what macOS version is this?

Another option is to use our own string in this particular case. It won't be localized, though.

@danmoseley
Copy link
Member

I'll reactivate this for that suggestion.

@danmoseley danmoseley reopened this Oct 31, 2017
@galvesribeiro
Copy link
Member

Darwin GUTO-MAC-PRO.local 17.0.0 Darwin Kernel Version 17.0.0: Thu Aug 24 21:48:19 PDT 2017; root:xnu-4570.1.46~2/RELEASE_X86_64 x86_64

image

@danmoseley
Copy link
Member

@stephentoub on High Sierra ENXIO gives "Device not configured" apparently instead of "No such device or address". Would it be reasonable for us to use our own string for this error code, possibly on macOS only?

@stephentoub
Copy link
Member Author

Would it be reasonable for us to use our own string for this error code, possibly on macOS only?

Is there a better errno value we could map to instead? EADDRNOTAVAIL? EHOSTUNREACH?

@danmoseley
Copy link
Member

As above, EHOSTUNREACH is misleading as it means that we have an IP address, which we don't.
EADDRNOTAVAIL seems to be for cases where the server is overloaded with connections but maybe its message is reasonable. @galvesribeiro any interest in replacing ENXIO with EADDRNOTAVAIL in src\Common\src\System\Net\Sockets\SocketErrorPal.Unix.c and letting us know what message you get ?

@galvesribeiro
Copy link
Member

@danmosemsft Sorry, I just got out on vacation with limited access to computer. If none else try that, I can try Dec 3th when I got back.

@games
Copy link

games commented Mar 5, 2018

I had same issue on my Mac, just fixed like what @CleverCoder said as above, adding the machine name to the /etc/hosts file (at least on MacOS), with 127.0.0.1 as the address.

MacOS:
sierra
10.12.6

@banyucenter
Copy link

Just edit localhost using 127.0.0.1
connstring = @"server=127.0.0.1;userid=root;password=;database=your_db";

@wfurt
Copy link
Member

wfurt commented Sep 6, 2018

I wrote simple C program:

#include <stdio.h>
#include <errno.h>
#include <string.h>

int main(int argc, char ** argv){
    printf("ENXIO: %s\n",strerror(ENXIO));
    printf("EADDRNOTAVAIL: %s\n",strerror(EADDRNOTAVAIL));
    printf("ENONET: %s\n", "?????");
    printf("EHOSTDOWN: %s\n",strerror(EHOSTDOWN));
    printf("EDESTADDRREQ: %s\n",strerror(EDESTADDRREQ));
    printf("ENOENT: %s\n",strerror(ENOENT));

    return 0;
}

on Linux:

ENXIO: No such device or address
EADDRNOTAVAIL: Cannot assign requested address
ENONET: Machine is not on the network
EHOSTDOWN: Host is down
EDESTADDRREQ: Destination address required
ENOENT: No such file or directory

OSX:

ENXIO: Device not configured
EADDRNOTAVAIL: Can't assign requested address
ENONET: ?????
EHOSTDOWN: Host is down
EDESTADDRREQ: Destination address required
ENOENT: No such file or directory

FreeBSD

ENXIO: Device not configured
EADDRNOTAVAIL: Can't assign requested address
ENONET: ????
EHOSTDOWN: Host is down
EDESTADDRREQ: Destination address required
ENOENT: No such file or directory

strangely, "no such file" seems most intuitive. For comparison, Curl HTTP Handler throws " Couldn't resolve host name". I think the flaw is attempt to map NDS error to errno and than use strerror() instead of gai_strerror()
Since SocketError.HostNotFound is distinct code, we should be able to find way how to do the mapping properly.

@schulz-m
Copy link

I have 2 WiFI Networks at home and I have the same issue on .NET Core 2.0. The following Error appears:

Unhandled Exception: System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: Device not configured
   at System.Net.Dns.InternalGetHostByName(String hostName, Boolean includeIPv6)
   at System.Net.Dns.GetHostEntry(String hostNameOrAddress)

As I can easily reproduce the error switching from one network to the other, I could help someone more experienced track down the difference and what's causing this.

@wfurt
Copy link
Member

wfurt commented Sep 24, 2018

The error is misleading. This is caused by DNS lookup failures. It seems like one of you networks does have some issues. You can try to resolve the name with nslookup, just to see if it is working properly.

@joelluijmes
Copy link

joelluijmes commented Oct 4, 2018

Just out of the blue I got this exception using Npgsql.

      Entity Framework Core 2.1.2-rtm-30932 initialized 'EntityFrameworkDbContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: SensitiveDataLoggingEnabled
Application startup exception: System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (00000005, 6): Device not configured
   at System.Net.Dns.InternalGetHostByName(String hostName)
   at System.Net.Dns.GetHostAddresses(String hostNameOrAddress)
   at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 663
   at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 555
   at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 414
   at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<<Open>g__OpenLong|0>d.MoveNext() in C:\projects\npgsql\src\Npgsql\NpgsqlConnection.cs:line 274

For me it didn't get fixed by adding my the hostname to /etc/hosts

⋊> ~/D/P/f/deployment on master ⨯ hostname                                                                                                                                                                                                                          22:33:45
MBP-Joell
⋊> ~/D/P/f/deployment on master ⨯ cat /etc/hosts                                                                                                                                                                                                                    22:33:47
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1	localhost MBP-Joell MBP-Joell.local
255.255.255.255	broadcasthost
::1             localhost
⋊> ~/D/P/f/deployment on master ⨯ nslookup MBP-Joell.local                                                                                                                                                                                                          22:33:50
Server:		192.168.1.1
Address:	192.168.1.1#53

** server can't find MBP-Joell.local: NXDOMAIN

⋊> ~/D/P/f/deployment on master ⨯ nslookup MBP-Joell                                                                                                                                                                                                                22:33:57
Server:		192.168.1.1
Address:	192.168.1.1#53

Non-authoritative answer:
Name:	MBP-Joell
Address: 192.168.1.23

However the most interesting part: is that the exception only raises when starting the application from command line (dotnet run). When starting with debugger using vscode, no exception is thrown.

--

EDIT / Solution: Apparently I forgot to set the environment variable, which configures which connection string I use.. Being that the connection string defaults that should be ran in docker-compose, it is a hostname that is unable to resolve outside that network.

So maybe the error message is just misleading, and should it report something along the lines of "Failed to lookup 'xxx'". Please do, include the value of the parameter that has been given, that would have saved me quite some time.

@chase9
Copy link

chase9 commented Oct 8, 2018

Just thought I'd contribute what I've found out while running into this same issue.

I was having trouble with the SendPingAsync() method of Ping. It turns out that the problem was caused by including http:// or https:// in the hostname, and indeed including this also caused the ping command to fail in the terminal.

I got around this by creating a Uri with uri builder, then passing in the host to ping. Here's my workaround:

Uri uri;

if (Uri.TryCreate(distributor.server, UriKind.Absolute, out uri))
{
    Ping _ping = new Ping();
    PingReply _reply = await _ping.SendPingAsync(uri.Host, 4000);

    if (_reply.Status == IPStatus.Success)
        return Ok(true);
}
return Ok(false);

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the 3.0 milestone Jan 31, 2020
@kalexico
Copy link

I have solve this problem using 127.0.0.1 address instead "localhost" as server name.

@tenoriojuann
Copy link

I was having trouble with the SendPingAsync() method of Ping. It turns out that the problem was caused by including http:// or https:// in the hostname, and indeed including this also caused the ping command to fail in the terminal.

Thank you!!!

I was connecting to a server using a corporate proxy and kept getting Device not configured.

By removing the protocol from the proxy I was able to connect just fine.

@ghost ghost locked as resolved and limited conversation to collaborators Dec 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net enhancement Product code improvement that does NOT require public API changes/additions os-mac-os-x macOS aka OSX
Projects
None yet
Development

No branches or pull requests