Runtime: "Device not configured" from Dns.GetHostEntryAsync on macOS

Created on 3 Nov 2016  Â·  34Comments  Â·  Source: dotnet/runtime

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()
area-System.Net enhancement os-mac-os-x

Most helpful comment

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

All 34 comments

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

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

@Priya91 can you please help here?

@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.

An ip address

On Thu, 19 Jan 2017 at 02:50, Lakshmi Priya Sekar notifications@github.com
wrote:

@jchannon https://github.com/jchannon What is the host value for which
you get this error?

—
You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/dotnet/corefx/issues/13309#issuecomment-273667855,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAGapoOXYUikeP6wKmN8tZwpcC-dzHvvks5rTs9_gaJpZM4KoYFg
.

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>

@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,

```C#
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.

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.

@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 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)?

@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 ...

@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:: 
[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.

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);

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.

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

@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.

@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.

"Device not configured" is what strerror gives for ENXIO, which is what we are supplying it for the HostNotFound case:
c# { 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.

I'll reactivate this for that suggestion.

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

@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?

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?

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 ?

@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.

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

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

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.

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.

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.

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

```info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
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.<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.

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);

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

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GitAntoinee picture GitAntoinee  Â·  3Comments

jchannon picture jchannon  Â·  3Comments

btecu picture btecu  Â·  3Comments

EgorBo picture EgorBo  Â·  3Comments

chunseoklee picture chunseoklee  Â·  3Comments