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

Open
#9,338 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.