How to Fix Ethernet on a Hackintosh: Kexts, Device Properties, and Troubleshooting

Step-by-step guide to resolving Ethernet issues on Hackintosh builds, from kext selection and device-property injection to power management fixes for Intel I210, Realtek, and dual-CPU systems.

Seeing your Ethernet port listed in System Information but never getting a green link light or a DHCP lease? That’s a classic Hackintosh headache. The hardware is almost never the culprit — it’s almost always a missing or misconfigured kernel extension (kext) or a property injection the bootloader never applied. Over the years, I’ve debugged Ethernet on everything from an Intel 82574L on a GA-P35-DS3L to the dual Intel I210-AT ports on an X99 board. The failure pattern is remarkably consistent: the user installed the correct kext but didn’t verify it actually loaded, or left a conflicting kext claiming the same PCI device ID.

Before reaching for a debugger or serial cable, confirm the Ethernet controller is visible on the PCI bus and that macOS has a kext that knows how to talk to it. Open System Information (or system_profiler in Terminal) and look under Ethernet Cards. If you see a vendor and device ID but no driver name, or if the field is empty, the kext either isn’t installed or isn’t matching the hardware. If the controller doesn’t appear at all, the problem may be at the ACPI level — some boards disable the Ethernet controller in the DSDT if the operating system isn’t Windows, and you’ll need a small SSDT patch to re-enable it. I covered this scenario in detail in Guide 226: ACPI Fixes for Sandy Bridge and Haswell Hackintosh, which includes the _OSI-to-XOSI rename trick that many Z77 and Z87 boards require.

Choosing the Correct Kext for Your Controller

Apple has built-in support for a handful of Intel and Broadcom controllers, but for the vast majority of desktop Ethernet chipsets — Realtek, older Intel PRO/1000, some Atheros, and the Intel I21x series — you need a third-party kext. The two most reliable options are AppleIGB.kext (for Intel I210 and I211) and RealtekRTL8111.kext (for Realtek 8111/8168/8100 families). For Intel 82574L, 82579V, and 82583V, IntelMausi.kext (version 1.0.2 or later) works on macOS Sierra through High Sierra. For older Intel controllers like the 82566 or 82573, you may need AppleIntelE1000e.kext, a direct port of the Intel Linux driver that supports chips back to the 82540.

There’s a persistent myth that you can simply drop any of these kexts into /Library/Extensions and reboot. That works only if SIP is fully disabled and you rebuild the kernel cache manually — not a recommended workflow for a production system. Instead, always inject the kext through your bootloader. In Clover, place the kext in /EFI/CLOVER/kexts/Other/ and ensure InjectKexts is set to Yes (or Detect). In OpenCore, place the kext in /EFI/OC/Kexts/ and add a corresponding entry in config.plist under Kernel -> Add, with the correct bundle path and Enabled set to True. Don’t skip the plist entry — OpenCore won’t load a kext that isn’t listed.

Device-Property Injection for Built-In Status

Once the kext is loaded and the interface appears in Network preferences, you may notice that macOS still treats it as an external USB adapter rather than a built-in Ethernet port. The symptom: the interface name shows as en0 but System Information under Ethernet Cards says “This computer does not appear to have any built-in Ethernet interfaces.” This is cosmetic for most users, but it can break services like AirDrop that rely on the built-in flag, and it prevents some third‑party firewall tools from binding to the correct interface.

To mark the port as built-in, add a device property to the Ethernet controller’s PCI device path. In Clover, use an AddProperties block in config.plist. The key is built-in, the value is 01 (or 0x01 in data format), and the device path is the full ACPI path to the Ethernet controller — typically _SB.PCI0.RP01.PXSX or _SB.PCI0.GLAN. You can find the exact path by looking at the IORegistry under IOService:/AppleACPIPlatformExpert/PCI0@0 and searching for the device with IONameMatch equal to your controller’s model string.

In OpenCore, the same property is injected via the DeviceProperties -> Add section. The key is the PCI device path (e.g., PciRoot(0x0)/Pci(0x1c,0x4)/Pci(0x0,0x0)), and under that you add a child dictionary with built-in as Data type and value 01. After rebooting, the Ethernet card should appear as “Built-in” in System Information. If it doesn’t, double-check the device path — even one extra segment or a missing function number will silently fail.

Diagnosing Link and Speed Issues

Even with the correct kext and built-in property, you may find the link doesn’t come up, or the interface negotiates at 100 Mbit instead of 1000. First, rule out the cable and switch — try a known-good Cat 5e or Cat 6 cable and a different port on your router or switch. If the link still fails, the issue is likely a power management conflict. Many Ethernet controllers enter a low-power state when the system sleeps, and if the kext doesn’t properly handle the wake sequence, the link stays down until a full reboot.

Test this by running sudo ifconfig en0 down followed by sudo ifconfig en0 up in Terminal. If the link comes back, the problem is reproducible. Look for a darkwake boot argument or a power management patch. In Clover, add darkwake=0 to the boot arguments in config.plist. In OpenCore, set Misc -> Boot -> HibernateMode to None and add -no_compat_check only if you’re on an unsupported OS version. For stubborn cases, disable Wake on LAN in the BIOS or use a small SSDT that forces the Ethernet controller’s power state to D0 on wake.

If the link negotiates at 100 Mbit when you expect 1000, check the wiring and switch port first. If those are fine, try forcing the speed and duplex via networksetup: sudo networksetup -setMTU en0 1500 followed by sudo ifconfig en0 media 1000baseT full-duplex. Some older Realtek controllers have a bug where they advertise only 100 Mbit after a warm reboot; a full power cycle (shut down, unplug for 30 seconds) often resolves this. If the problem persists on a Realtek 8111, consider switching to RealtekRTL8111.kext version 2.2.2 or later, which includes a fix for this exact issue.

Ethernet on Dual-CPU and X99 Systems

Dual-CPU workstations and X99 enthusiast boards often use Intel I210 or I211 controllers, which are well supported but require careful kext selection. AppleIGB.kext (version 1.0.2 or later) works on Sierra through High Sierra, but only if you also inject the device-id property to spoof the I211 as an I210. The I211 has a different PCI device ID (0x1539) than the I210 (0x1533), and AppleIGB.kext doesn’t natively match the I211. In the DeviceProperties section of your config, add a property device-id with type Data and value 33150000 (little-endian 0x1533) on the I211 device path. I’ve verified this on several X99 dual-CPU builds, and it consistently enables full Gigabit Ethernet.

For users working with dual-CPU X79 and X99 configurations, the Ethernet controller is often connected to a PCIe slot routed through the second CPU’s PCIe root complex. In such cases, you may need an additional ACPI patch to ensure the controller is visible to macOS. The Dual-CPU X99 Hackintosh Update: High Sierra, Clover r5123, and What to Watch For includes a section on the SSDT-EC patch that resolves Ethernet enumeration on systems where the controller appears under a secondary PCI bus. Always verify the controller’s location in IORegistry before applying any ACPI changes — patching the wrong device can cause kernel panics on boot.

Testing and Persistence

After applying any kext or property injection, test the Ethernet connection by pinging your router’s IP address (ping 192.168.1.1 or whatever your gateway is). Don’t test by browsing the web — DNS failures can mask a working link. If pings succeed, run sudo dmesg | grep -i "en0" to confirm that the kext loaded and reported the link state correctly. For long-term stability, create a backup of your working config.plist and kext folder before making further changes. Ethernet is one of those subsystems that, once working, should remain stable across reboots and sleep cycles — but only if you document the exact kext version and property injection that got it there.