googleapis / googleapis/google-cloud-node
gcp-metadata: macOS AWDL interface with a 42:01 MAC is detected as GCE; METADATA_SERVER_DETECTION=none is then ignored and metadata requests hang
- Dominant language
- TypeScript
- Stars
- 3.2k
- Forks
- 712
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 99
Description
### Library Name
`gcp-metadata` (with `google-auth-library`)
### A screenshot that you have tested with "Try this API"
N/A. This is local environment detection in the client library, and no API call is involved.
### Link to the code that reproduces this issue
https://gist.github.com/A13k2/9461bca8cbfdb9d286a8ff2826cd96e6
### Steps to reproduce
1. `npm i google-auth-library gcp-metadata`
2. `METADATA_SERVER_DETECTION=none HOME=$(mktemp -d) node repro.js`
The script adds a fake `awdl0` interface with MAC `42:01:d6:57:43:fd` to `os.networkInterfaces()`, which is what an affected Mac reports. It then prints `detectGCPResidency()` and `requestTimeout()` and calls `new GoogleAuth().getClient()`. Set `REAL_INTERFACES=1` to skip the fake interface.
Output on macOS 26.6, Node 22.23.1:
```
== google-auth-library 9.15.1 / gcp-metadata 6.1.1
detectGCPResidency(): true
requestTimeout(): 0 (0 = no timeout)
getClient(): still pending after 15000ms
== google-auth-library 11.0.2 / gcp-metadata 9.0.3
detectGCPResidency(): true
requestTimeout(): 0 (0 = no timeout)
getClient() resolved with Compute after 2383 ms
== control, same machine with awdl0/llw0 down
detectGCPResidency(): false
requestTimeout(): 3000
getClient(): Could not load the default credentials. ... after 0 ms
```
### What the bug is, and what I expected
On macOS, the Apple Wireless Direct Link interfaces (`awdl0`, `llw0`, used by AirDrop and Continuity) use a randomized, locally administered MAC address. On my machine that address currently starts with `42:01` (`ether 42:01:d6:57:43:fd`). `isGoogleComputeEngineMACAddress()` matches any interface against `/^42:01/`, so `detectGCPResidency()` returns `true` on an ordinary laptop.
After that:
- `GoogleAuth._checkIsGCE()` runs `gcpMetadata.getGCPResidency() || await gcpMetadata.isAvailable()`. The residency check short-circuits, so `METADATA_SERVER_DETECTION=none` is never read.
- `requestTimeout()` returns `0`, so metadata requests to `169.254.169.254` have no timeout.
The result is that `firebase emulators:start` hangs indefinitely before the Functions emulator starts, and the process sits in `SYN_SENT` to `169.254.169.254:80`. Setting `METADATA_SERVER_DETECTION=none`, the documented escape hatch from googleapis/gcp-metadata#548, has no effect. Toggling Wi-Fi does not change the AWDL MAC. The only fix I found is `sudo ifconfig awdl0 down && sudo ifconfig llw0 down`.
I expected at least one of these:
1. `METADATA_SERVER_DETECTION=none` is honoured even when the MAC check matches, so it overrides detection.
2. The MAC check is skipped outside Linux, or skips interfaces that can't be GCE NICs (such as `awdl*`/`llw*` or link-local-only interfaces). GCE VMs run Linux or Windows, never macOS.
### Why I expect this
- The `METADATA_SERVER_DETECTION` docs in `gcp-metadata` describe `none` as "don't try to ping the metadata server, but don't try to use it either". Today it only applies when the residency check says no.
- `42:01` falls in the locally administered MAC range, which any OS can pick at random, so matching it alone is not a reliable sign of GCE. macOS assigns these addresses to AWDL by design.
- Related: firebase/firebase-tools#7566 reports the same `_checkIsGCE()` bypass of `METADATA_SERVER_DETECTION` from the emulator side. This issue gives a concrete trigger for it on macOS.
Contributor guide
Research direction
Run the linked repro.js with the fake awdl0 interface and METADATA_SERVER_DETECTION=none. Then trace detectGCPResidency(), isGoogleComputeEngineMACAddress(), GoogleAuth._checkIsGCE(), and requestTimeout(). Done means ordinary macOS AWDL interfaces no longer cause false GCE detection, and the documented detection setting prevents an unbounded metadata request.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- google-cloud, node.js, typescript
- Domain
- authentication, cloud
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100