{"record":{"id":"b5996b134f27b12c","repo":"slackhq/nebula","slug":"inetworkconnection-getadapterid-s","errorCode":null,"errorMessage":"INetworkConnection.GetAdapterId: %s","messagePattern":"INetworkConnection\\.GetAdapterId: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"overlay/network_category_windows.go","lineNumber":188,"sourceCode":"\tGetConnectivity       uintptr\n\tGetConnectionId       uintptr\n\tGetAdapterId          uintptr\n\tGetDomainType         uintptr\n}\n\ntype iNetworkConnection struct{ Vtbl *iNetworkConnectionVtbl }\n\nfunc (c *iNetworkConnection) Release() {\n\tsyscall.SyscallN(c.Vtbl.Release, uintptr(unsafe.Pointer(c)))\n}\n\nfunc (c *iNetworkConnection) GetAdapterId() (windows.GUID, error) {\n\tvar g windows.GUID\n\tr1, _, _ := syscall.SyscallN(c.Vtbl.GetAdapterId,\n\t\tuintptr(unsafe.Pointer(c)), uintptr(unsafe.Pointer(&g)),\n\t)\n\tif hr := hresult(r1); hr.failed() {\n\t\treturn windows.GUID{}, fmt.Errorf(\"INetworkConnection.GetAdapterId: %s\", hr)\n\t}\n\treturn g, nil\n}\n\nfunc (c *iNetworkConnection) GetNetwork() (*iNetwork, error) {\n\tvar net *iNetwork\n\tr1, _, _ := syscall.SyscallN(c.Vtbl.GetNetwork,\n\t\tuintptr(unsafe.Pointer(c)), uintptr(unsafe.Pointer(&net)),\n\t)\n\tif hr := hresult(r1); hr.failed() {\n\t\treturn nil, fmt.Errorf(\"INetworkConnection.GetNetwork: %s\", hr)\n\t}\n\treturn net, nil\n}\n\ntype iNetworkVtbl struct {\n\tiDispatchVtbl\n\tGetName                    uintptr","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/overlay/network_category_windows.go#L170-L206","documentation":"This error wraps a failed HRESULT from INetworkConnection::GetAdapterId, a COM call used during Windows network category detection to correlate a network connection with its adapter GUID. A failing HRESULT means the NLM COM object refused or failed the call (service unavailable, stale connection pointer, or permission problem).","triggerScenarios":"Calling GetAdapterId() on an iNetworkConnection pointer obtained from the enumerator while classifying the tunnel adapter's network, when the COM vtbl call returns a failed HRESULT.","commonSituations":"The connection object became stale after a network change (adapter removed, VPN adapter recreated); NLM service instability; running in restricted service contexts where NLM queries are denied.","solutions":["Re-enumerate network connections to get fresh iNetworkConnection pointers, then retry GetAdapterId","Verify the Network List Service (netprofm) is healthy and running","Ensure the COM call runs in the same apartment/thread where the object was created","Inspect the hresult in the message for the exact COM error (e.g. RPC_E_DISCONNECTED) and handle stale-object cases by refreshing the enumeration"],"exampleFix":"// before\nadapterId, err := conn.GetAdapterId()\nif err != nil { return err }\n// after: refresh stale connections once\nadapterId, err := conn.GetAdapterId()\nif err != nil {\n    if refreshed, rerr := refreshConnections(); rerr == nil {\n        adapterId, err = refreshed.GetAdapterId()\n    }\n    if err != nil { return err }\n}","handlingStrategy":"retry","validationCode":"// ensure the connection pointer is fresh before querying\nif connsStaleAt.After(netProfileChangedAt) {\n    conns, err = nlm.GetNetworkConnections() // re-enumerate\n    if err != nil { return err }\n}","typeGuard":"func isAdapterIdError(err error) bool {\n    return err != nil && strings.HasPrefix(err.Error(), \"INetworkConnection.GetAdapterId:\")\n}","tryCatchPattern":"var adapterId windows.GUID\nvar err error\nfor i := 0; i < 2; i++ {\n    adapterId, err = conn.GetAdapterId()\n    if err == nil { break }\n    if conn, err = refreshConnection(); err != nil { break }\n}\nif err != nil { log.Warnf(\"adapter id lookup failed: %v\", err) }","preventionTips":["Re-enumerate connections after adapter up/down events before querying","Keep NLM object usage on the creating thread","Check for RPC_E_DISCONNECTED-style hresults indicating stale pointers","Skip classification non-fatally when the adapter is mid-reconfiguration"],"tags":["windows","com","winapi","adapter"],"backgroundTag":"com-call-failed","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}