{"record":{"id":"811664c4abc5af93","repo":"netbirdio/netbird","slug":"read-of-the-policy-table-timed-out","errorCode":null,"errorMessage":"read of the policy table timed out","messagePattern":"read of the policy table timed out","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"client/internal/debug/nrpt_windows.go","lineNumber":94,"sourceCode":"\n\tdone := make(chan result, 1)\n\tgo func() {\n\t\t// the slot is released here rather than by the caller, so a read that\n\t\t// outlives the timeout holds it until the provider answers\n\t\tdefer func() { <-nrptQueryInFlight }()\n\n\t\ttext, err := nrptPolicyTableText()\n\t\tdone <- result{text: text, err: err}\n\t}()\n\n\tselect {\n\tcase res := <-done:\n\t\tif res.err != nil {\n\t\t\treturn nil, res.err\n\t\t}\n\t\treturn parseNRPTPolicyTable(res.text), nil\n\tcase <-time.After(nrptPolicyTimeout):\n\t\treturn nil, errors.New(\"read of the policy table timed out\")\n\t}\n}\n\n// nrptPolicyTableText calls the policy table method and returns the MOF text of\n// its out parameters.\nfunc nrptPolicyTableText() (text string, err error) {\n\t// COM is per thread, and the collection is short lived, so the thread is\n\t// pinned for the duration rather than initialized for the process.\n\truntime.LockOSThread()\n\tdefer runtime.UnlockOSThread()\n\n\tdefer func() {\n\t\t// The COM call chain is dynamically typed, so a provider that answers\n\t\t// with an unexpected shape must not take the daemon down with it.\n\t\tif r := recover(); r != nil {\n\t\t\terr = fmt.Errorf(\"read NRPT policy table: %v\", r)\n\t\t}\n\t}()","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/internal/debug/nrpt_windows.go#L76-L112","documentation":"Debug endpoint error from handleClientStatus (proxy/internal/debug/handler.go:425): the requested accountID has no live embedded management client (nbembed.Client) in the provider's registry, so the debug UI/API answers 404 'Client not found: <accountID>'. The provider maps types.AccountID to per-account embedded clients spawned by the proxy.","triggerScenarios":"GET /debug/clients/<accountID>/status (or the ?json variant) with an accountID that was never registered, whose client has not started yet, or whose client was removed (account deregistered or listener torn down); also a mistyped or URL-escaped ID.","commonSituations":"Operator copies an account ID from an older incident after the account disconnected; racing the debug UI against client startup; account removed from management so the proxy dropped its client.","solutions":["List live accounts first via the clients overview (ListClientsForDebug-backed page or endpoint) and use an ID that appears there.","If the account should be live, check the proxy logs for why its client is not running (management sync failure, removed domain).","URL-encode the account ID exactly as shown by the list view."],"exampleFix":"# before\ncurl http://proxy-debug/debug/clients/<stale-or-typo-id>/status\n# -> 404 Client not found: <id>\n\n# after: enumerate live accounts, then query one of them\ncurl http://proxy-debug/debug/clients | jq 'keys'\ncurl http://proxy-debug/debug/clients/<id-from-list>/status","handlingStrategy":"validation","validationCode":"// Call the list endpoint first and only query IDs it returns.\nresp, err := http.Get(debugBase + \"/clients\")\nif err != nil {\n    return err\n}\nvar live map[string]any\nif err := json.NewDecoder(resp.Body).Decode(&live); err != nil {\n    return err\n}\nif _, ok := live[accountID]; !ok {\n    return fmt.Errorf(\"account %s not live; pick from %d known\", accountID, len(live))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always enumerate live clients before deep-linking to a per-account debug page.","Re-check the list after proxy restarts or account changes.","Treat 404 'Client not found' as 'not live (yet)', not as an error to page someone for."],"tags":["proxy","debug","http","observability"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}