NativeEthernet.h hangs NativeEthernet.cpp, while(!link_status){ } (line293) WHY???


Well-known member
The NativeEthernet.h hangs at Ethernet.begin( unless the Ethernet cable is connected and link ok. the NativeEthernet.cpp seems to have
while(!link_status){ } (line293) WHY??? how am I supposed to get on setup past Ethernet.begin( if the network is not yet correctly configured, so that I could use terminal to set IP , mask etc. so that it would work? Is there any other solution to this than to modify the NativeEthernet.cpp?
I found kind of workaround, I am using fixed IP, with it, it does not seem to get through unless link status ok. but like this it gets past the Ethernet.begin after a minute or so even when cable not connected. (this is on Teensy 4.1)

      Ethernet.begin(mac); //it goes trough this after a minute or so , but not Ethernet.begin(mac, ip, subnet);
      Serial.println("Ethernet initialised.");


void loop()

if (Ethernet.linkStatus() == LinkON) {
    if (!networkInitialized) {
      Ethernet.begin(mac, ip, subnet);
      Serial.println("Ethernet cable is connected.");
      Serial.print("Server is at "); Serial.println(Ethernet.localIP());
      networkInitialized = true;
  } else {
    if (networkInitialized) {

It would be good to be able to do some basic initialisation without actually seting up the parameters, to get Ethernet.linkStatus() and when link is
LinkON, then setup the parameters, like the above code does now, but reguires a long wait to get trough Ethernet.begin(mac);, a bit more than a minute, and with the above code one needs to wait that every time it is started, so not good.
Last edited:

Maybe try using QNEthernet (newer/better Ethernet stack, excellent examples available, actively maintained by @shawn who is on this forum) instead of NativeEthernet (older).

See <this> thread for specific mention of the problem that you are seeing . . .

Mark J Culross
I think it was an attempt to make the library behave the same as a remembered past version, for compatibility with existing past code.

A post with some history:

An additional note:
The original Arduino Ethernet library was essentially a model of how to do things with the WIZnet chips over SPI. Its design reflected that, and I don't think it's an appropriate model for how to do things with other sorts of chips and peripherals. However, there's an existing code base and API, so there's still that to consider. I've made efforts to keep QNEthernet compatible with this API, while slowly steering away from it. My strategy is to have lots of additional functionality, such as callbacks (eg. for link state) and lots of other capabilities, while still being backwards compatible. I'm thinking about eventually removing the parts of the Arduino-style API I'm not fond of from the main library, and separating that into a separate layer, so there's both a better API and backwards compatibility, but without forcing users who want something newer to keep that part.

It sounds like you want to only do certain things after the link is up. There's a few ways to do this:
1. Use the onLinkState() callback to notify on a change of state. Note that no network tasks should be performed inside the listeners. Instead, set a flag and then process that flag somewhere from the main loop.
2. You could use the simple Ethernet.waitForLink(timeout) approach; it returns a Boolean indicating success within the given timeout.
3. Poll the link via linkState() (or the non-Boolean-returning linkStatus()) somewhere from your main loop.

That's how to detect a link.

Some more notes:
1. You can do things like start servers before the link is up.
2. I noticed in your code that you call Ethernet.begin() after the link is detected. This won't work (at least with QNEthernet; I'm not sure about other libraries) because nothing will happen unless Ethernet.begin(...) is called at program startup. In other words, call begin(...) first. You can, however, set up callbacks before calling begin(...) so no events are missed. (The README says: "...callbacks should be registered before any other Ethernet functions are called. This ensures that all events are captured. This includes Ethernet.begin(...).")
3. You don't need to specify a MAC address. To use DHCP: Ethernet.begin(). To use a static IP: Ethernet.begin(ip, mask, gateway). They both return a Boolean indicating a successful start. With DHCP, the IP will come up later (See Ethernet.onAddressChanged() or Ethernet.waitForIP(timeout), or even localIP().)
4. Check out the examples that come with the library for a variety of ways of doing things. Think of them as a supermarket; the more complex examples have concepts you can cherry-pick.

Some relevant README links:
1. (no need to worry about the interface-up listener).
Thanks for the answers, I have now tested a bit with QNEthernet.h and it removes the startup issue, but seems to have some problems with my REST API implementation, works but after some receptive updates, the update rate comes very slow. This could very well be my primitive REST API at this time, and how I use QNEthernet.h (or do not know how to use it)

The basically same REST API implementation on NativeEthernet.h does not seem to have this slowdown issue with receptive data. Will continue to experiment with these.
After reviewing the licensing terms, though it is not critical at this time, I can not use QNEthernet.h, so have to find solution for the startup problem with no ethernet or wrongly configured ethernet to get the code running despite that with the

I just do not understand, is the idea the NativeEthernet.h fixed IP settings should be correctly hardcoded? as you will not get pass
Ethernet.begin(mac, ip, subnet); if it is not correctly configured. ANd sometimes maybe you will not have Ethernet connected on purpose. For me this would be typical, using USB serial and/or HW serial or Ethernet. And sometimes all of them
Last edited: