{"record":{"id":"6083b4882435e0bb","repo":"netbirdio/netbird","slug":"failed-to-get-config-v","errorCode":null,"errorMessage":"failed to get config: %v","messagePattern":"failed to get config: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/cmd/debug.go","lineNumber":138,"sourceCode":"\t}\n\n\tconn, err := getClient(cmd)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer func() {\n\t\tif err := conn.Close(); err != nil {\n\t\t\tlog.Errorf(errCloseConnection, err)\n\t\t}\n\t}()\n\n\tclient := proto.NewDaemonServiceClient(conn)\n\tresp, err := client.GetConfig(cmd.Context(), &proto.GetConfigRequest{\n\t\tProfileName: string(activeProf.ID),\n\t\tUsername:    currUser.Username,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get config: %v\", status.Convert(err).Message())\n\t}\n\n\t// Use protojson so well-known fields render correctly; emit defaults so\n\t// the operator sees every field even when zero/empty.\n\tm := protojson.MarshalOptions{Multiline: true, Indent: \"  \", EmitUnpopulated: true}\n\tout, err := m.Marshal(resp)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal config: %w\", err)\n\t}\n\tcmd.Println(string(out))\n\treturn nil\n}\n\n// debugBundle requests the daemon to create a debug bundle and prints\n// the resulting local file path and, if uploaded, the uploaded file\n// key. It uses the package flags (anonymize, system info, log file\n// count, CLI version, optional upload URL) to configure the bundle\n// request. Returns an error if the RPC fails or if the daemon reports","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/cmd/debug.go#L120-L156","documentation":"The GetConfig RPC to the daemon failed. Note the CLI deliberately drops the gRPC envelope and prints only status.Convert(err).Message(), so what you see is the daemon-side message text, not a transport error string. Failures come in two families: transport (daemon not running, socket/named pipe unreachable) — where the message is typically 'failed to connect...' or 'error reading from server' — and handler-level refusals from the daemon (unknown profile, user mismatch).","triggerScenarios":"Daemon service stopped/crashed while the CLI tried to reach it (transport-level message); GetConfigRequest carries ProfileName/Username of the active profile but the daemon was reconfigured with a different profile set (unknown profile message); upgrading the daemon while an old CLI runs the dump; permission to the IPC socket denied for the calling user.","commonSituations":"netbird debug config-dump right after boot before the service starts; mixed versions during package upgrades; the daemon restarted with a cleared config directory while the CLI still had a profile pointer; running as a user without IPC access policy.","solutions":["Verify the daemon is running and healthy (systemctl status netbird / service logs), start it if needed, then rerun","Compare versions: netbird version (CLI) vs the daemon log banner; align them if an upgrade left them mismatched","If the message names a missing profile, re-run netbird up/login so the daemon and CLI profile stores agree, then retry the dump","Run the command as the user owning the profile and with access to the daemon IPC socket (the same user netbird up was run for)"],"exampleFix":"# before: dump attempted while the service is stopped\nnetbird debug config-dump\n# -> failed to get config: ...\n\n# after: daemon up first\nsudo systemctl start netbird && netbird debug config-dump","handlingStrategy":"retry","validationCode":"// Verify the daemon IPC endpoint answers before the RPC:\nconn, err := getClient(cmd) // connection already implies socket present\nif err != nil { return err }\n// optional:Ping service via a cheap RPC (e.g. Status) first\nif _, err := proto.NewDaemonServiceClient(conn).Status(cmd.Context(), &proto.EmptyRequest{}); err != nil {\n    return fmt.Errorf(\"daemon unhealthy: %v\", status.Convert(err).Message())\n}","typeGuard":null,"tryCatchPattern":"// Start-stop retry for service-not-yet-up races:\nresp, err := client.GetConfig(ctx, req)\nfor retry := 0; err != nil && retry < 3; retry++ {\n    time.Sleep(time.Duration(retry+1) * time.Second)\n    resp, err = client.GetConfig(ctx, req)\n}\nif err != nil {\n    return fmt.Errorf(\"failed to get config: %v\", status.Convert(err).Message())\n}","preventionTips":["Sequence scripts to wait for the service to be active before CLI calls (systemctl is-active netbird loop, or an readiness RPC)","Keep CLI and daemon on the same release","Run CLI commands as the profile-owning user to avoid IPC permission failures"],"tags":["grpc","daemon","config","cli","debug"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}