{"record":{"id":"fe3fead0a03ec42c","repo":"netbirdio/netbird","slug":"jwt-token-is-required","errorCode":null,"errorMessage":"jwt token is required","messagePattern":"jwt token is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/internal/engine_authsession.go","lineNumber":85,"sourceCode":"// T-WarningLead interactive notification and suppresses the upcoming\n// T-FinalWarningLead fallback for the current deadline. No-op when the\n// watcher is not running or holds no deadline.\nfunc (e *Engine) DismissSessionWarning() {\n\tif e.sessionWatcher == nil {\n\t\treturn\n\t}\n\te.sessionWatcher.Dismiss()\n}\n\n// ExtendAuthSession asks the management server to refresh the SSO session\n// expiry deadline using the supplied JWT, then mirrors the new deadline into\n// the daemon's state. The tunnel is untouched; no resync, no reconnect.\n//\n// Returns the new absolute UTC deadline (or zero time when the server\n// reports the peer is not eligible for extension).\nfunc (e *Engine) ExtendAuthSession(ctx context.Context, jwtToken string) (time.Time, error) {\n\tif jwtToken == \"\" {\n\t\treturn time.Time{}, errors.New(\"jwt token is required\")\n\t}\n\tif e.mgmClient == nil {\n\t\treturn time.Time{}, errors.New(\"management client is not initialised\")\n\t}\n\n\tinfo, err := system.GetInfoWithChecks(ctx, e.checks)\n\tif err != nil {\n\t\tlog.Warnf(\"failed to collect system info for session extend: %v\", err)\n\t\tinfo = system.GetInfo(ctx)\n\t}\n\n\tresp, err := e.mgmClient.ExtendAuthSession(info, jwtToken)\n\tif err != nil {\n\t\treturn time.Time{}, fmt.Errorf(\"extend auth session on management: %w\", err)\n\t}\n\n\te.ApplySessionDeadline(resp.GetSessionExpiresAt())\n","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/internal/engine_authsession.go#L67-L103","documentation":"Marshal failure in handleClientSyncResponse (proxy/internal/debug/handler.go:527): protojson's MarshalOptions{EmitUnpopulated, UseProtoNames, Indent, AllowPartial}.Marshal returns an error on the retrieved protobuf sync response. With AllowPartial already set, remaining causes are essentially unsupported/unknown fields or an internally inconsistent message (e.g. a field holding an invalid value such as a bad enum number), and the debug endpoint answers 500 with the marshal error.","triggerScenarios":"The stored *proto sync response contains data protojson refuses to serialize: an unknown field with unserializable content injected by a version skew between the proxy's compiled proto and what management sent, or an invalid enum/value that fails protojson's internal validation.","commonSituations":"Management newer/older than the proxy so the sync message contains unexpected field values; a partially populated message that even AllowPartial cannot render; corrupted in-memory state after deserialization issues.","solutions":["Check version alignment: the proxy's compiled protobuf definitions should match the management version that produced the sync response (redeploy matching versions).","Read the appended protojson error — it names the offending field.","Restart the affected account's client to re-fetch a fresh sync response and retry the endpoint.","If reproducible, capture the raw response and report it — a marshal failure on a server-produced message indicates a proto contract problem."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"jsonBytes, err := opts.Marshal(syncResp)\nif err != nil {\n    // Fallback: surface the failure explicitly instead of a bare 500 —\n    // render the error plus proto reflection info so the offending field\n    // is identifiable, and keep the rest of the debug page usable.\n    http.Error(w, \"Error marshaling sync response: \"+err.Error(), http.StatusInternalServerError)\n}","preventionTips":["Deploy proxy and management from matching versions so compiled protos agree with the messages received.","After version upgrades, hit the syncresponse endpoint for each live account as a smoke test.","A persistent marshal failure on a freshly synced response is a proto contract bug — capture and report it with version numbers."],"tags":["proxy","debug","protobuf","protojson","serialization"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}