How to Force Built-In Ethernet on Hackintosh (X79, Z77, Z87, Z97, X99)
Stop blaming kexts. Fix ‘Built-In: No’ on your Hackintosh by injecting device properties or patching ACPI _DSM. Step-by-step for Realtek, Intel, and Broadcom controllers.
Ethernet shows up as Built-In: No in System Information? Don't blame the kext. Most Hackintosh builders swap AppleRTL8169Ethernet.kext with RealtekRTL8111.kext, try every version of IntelMausi.kext, and still see the same result. The real cause is almost always a missing ACPI device path or a misconfigured device-id property in the boot loader. Here's how to force built-in status for onboard Ethernet controllers on X79, Z77, Z87, Z97, and X99 platforms running macOS Sierra through Mojave. The same approach works for High Sierra and Catalina, though the kext situation shifts slightly — I'll note those differences.
Why Built-In Matters
macOS uses the built-in property for two things: enabling Wake-on-LAN (WoL) and allowing iMessage/FaceTime activation via the en0 interface. Without this flag, the system treats the Ethernet port as a removable PCI device. iServices may still work if you use a patched SystemProfiler or a board-id trick, but WoL will remain broken. For a desktop Hackintosh that sleeps, built-in Ethernet is the difference between a machine that wakes on a magic packet and one that only wakes on power button press.
The property is set by the IONetworkingFamily kext during device matching. It reads the built-in key from the IORegistry entry of the network controller. If that key is missing or set to No, the driver does not advertise the interface as built-in. You can force it via a device property injection in Clover or OpenCore, or by fixing the ACPI _DSM method for the Ethernet device.
Identifying Your Ethernet Controller
Before injecting anything, confirm the exact PCI device. Open Terminal and run:
ioreg -l | grep -i ethernet
Look for the IOName or compatible string. Common entries:
- Realtek RTL8111/8168 — appears as
pci10ec,8168 - Intel I217-V / I218-V / I219-V — appears as
pci8086,15a3or similar - Broadcom BCM57781/57785 — less common on Z87/Z97, but present on some Gigabyte boards
If the device does not appear at all in IORegistry, the PCI device is not enumerated correctly — check your SSDT or DSDT for a missing _STA method that returns zero.
Method 1: Device Property Injection (Clover / OpenCore)
This is the safest approach because it does not touch ACPI tables. In Clover, edit config.plist under DeviceProperties → Add. You need the full PCI path of the Ethernet controller. Find it in IORegistry under IOService:/AppleACPIPlatformExpert/PCI0@0/.... For a typical Z77 board with Realtek onboard, the path might be PciRoot(0x0)/Pci(0x1C,0x4)/Pci(0x0,0x0). Add a dictionary with key built-in and value <01000000> (data type, 4 bytes, little-endian). Example:
<key>PciRoot(0x0)/Pci(0x1C,0x4)/Pci(0x0,0x0)</key>
<dict>
<key>built-in</key>
<data>AQAAAA==</data>
</dict>
In OpenCore, the same property goes under DeviceProperties → Add with the exact same PCI path and built-in as 01000000 (Data). Reboot and check IORegistry — the key should appear.
If the built-in property still shows No, the driver may be overriding it. Some third-party kexts (especially older RealtekRTL8111.kext v1.x) ignore the property entirely. Switch to AppleRTL8169Ethernet.kext for Realtek chips on Sierra/High Sierra, or use IntelMausiEthernet.kext for Intel controllers. For Mojave and later, RealtekRTL8111.kext v2.x respects the built-in property correctly.
Method 2: ACPI _DSM Patch (DSDT or SSDT)
If property injection does not work — for example, because your boot loader ignores the path due to a different PCI topology — you can add a _DSM method to the Ethernet device in ACPI. This is more invasive and requires extracting your DSDT, locating the Ethernet device (usually GLAN, GIGE, LAN0, or PXSX under PCI0), and inserting:
Method (_DSM, 4, NotSerialized)
{
If (LEqual (Arg2, Zero)) { Return (Buffer() { 0x03 } ) }
Return (Package()
{
"built-in", Buffer() { 0x01 },
"device-id", Buffer() { 0x68, 0x81, 0x00, 0x00 },
})
}
The device-id buffer above is for Realtek RTL8168 — adjust it for your controller. Compile with iasl, place the resulting .aml in EFI/CLOVER/ACPI/patched or EFI/OC/ACPI, and ensure your config loads it. This method forces macOS to see the device as built-in regardless of the driver. It is the same technique used in many pre-built SSDTs for Gigabyte Z77X-UD5H boards.
Be cautious: a malformed _DSM can cause the Ethernet device to fail matching entirely, leaving you with no network. Always test with a single ACPI table at a time. If you are already debugging ACPI errors, the article on Legacy Hackintosh ACPI Debugging: Decoding Error 226, 2, and 3 covers how to trap and interpret method failures during boot.
When Built-In Still Shows No After Both Methods
Several edge cases cause persistent failure:
- Duplicate device entries in IORegistry: Some boards expose the same MAC address under two PCI paths (one for the integrated NIC, one for a virtual function). macOS picks the wrong one. Disable the extra device in BIOS — usually labeled “Onboard LAN Controller #2” or “Virtual MAC”.
- Kext injection order: If you inject
AppleRTL8169Ethernet.kextandRealtekRTL8111.kextsimultaneously, they conflict. Keep only one. - BIOS setting “Wake on LAN” disabled: On some AMI BIOS versions, disabling WoL in firmware also clears the
built-inflag. Enable WoL even if you do not plan to use it. - Wrong Ethernet port: If your board has two physical RJ45 ports, only one is typically the “built-in” port that macOS recognizes as en0. The second port often shows as en1 with
Built-In: No. You can swap them by changing the BSD Name in/Library/Preferences/SystemConfiguration/NetworkInterfaces.plist, but the built-in flag will remain on the first port. Physically connect your cable to the port closest to the USB stack (usually the primary Intel or Realtek controller).
For X79 and X99 dual-CPU boards, the Ethernet controller often sits behind a PCIe bridge that macOS does not enumerate correctly. The _DSM method must be added to the bridge itself, not just the endpoint. The Building a Dual-CPU Hackintosh on X79 and X99: A Practical Guide includes a table of known bridge-to-endpoint paths for ASUS and Gigabyte workstation boards.
Testing and Verification
After applying either method, reboot and run:
ioreg -r -c IONetworkInterface | grep -E "BSD Name|built-in|IOMACAddress"
You should see "built-in" = Yes for en0. To verify WoL, put the machine to sleep and send a magic packet from another device on the same subnet. If the machine wakes within 5 seconds, the built-in flag is working. If it does not wake, check that the Ethernet link light stays on during sleep — if it goes dark, the controller lost power. Some boards require DarkWake to be enabled in ACPI.
For iMessage, built-in alone is not sufficient — you also need a valid board serial and MLB in the SMBIOS section. But without built-in Ethernet, iMessage will fail even with correct serials because the system cannot generate a unique en0 MAC-based identifier.
If you are running High Sierra beta builds (10.13.x), note that the built-in property detection changed between beta 2 and beta 5. The _DSM method that worked in Sierra may produce a kernel panic on early High Sierra builds. The post about June 2017: High Sierra Beta, Kaby Lake iGPU, and ACPI Stability documents exactly which _DSM return values caused panics on real hardware. If you are on a beta, prefer property injection over ACPI patching.
Preserving the Configuration
Once built-in works, back up the entire EFI folder — not just the config.plist. If you used an SSDT with the _DSM patch, keep a copy of the source .dsl file alongside the compiled .aml. Future macOS updates may change the IONetworkingFamily behavior, and you will need to recompile with a different return value. I keep a text file in the EFI partition called builtin_ethernet_notes.txt with the exact PCI path, the property injection dictionary, and the MAC address of the controller. That way, if the drive fails or I rebuild from scratch, I do not have to rediscover the path through trial and error.
One final check: after a macOS point update (e.g., 10.12.5 to 10.12.6), verify that built-in still appears. Some updates reset the IORegistry cache and require a reboot to re-apply the injected properties. If it disappears, a single reboot usually restores it — no re-patching needed.
