{"record":{"id":"27a8dd12996de55d","repo":"livekit/livekit","slug":"could-not-migrate-participant","errorCode":null,"errorMessage":"could not migrate participant","messagePattern":"could not migrate participant","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/routing/errors.go","lineNumber":34,"sourceCode":"\nimport (\n\t\"errors\"\n)\n\nvar (\n\tErrNotFound             = errors.New(\"could not find object\")\n\tErrIPNotSet             = errors.New(\"ip address is required and not set\")\n\tErrHandlerNotDefined    = errors.New(\"handler not defined\")\n\tErrIncorrectRTCNode     = errors.New(\"current node isn't the RTC node for the room\")\n\tErrNodeNotFound         = errors.New(\"could not locate the node\")\n\tErrNodeLimitReached     = errors.New(\"reached configured limit for node\")\n\tErrInvalidRouterMessage = errors.New(\"invalid router message\")\n\tErrChannelClosed        = errors.New(\"channel closed\")\n\tErrChannelFull          = errors.New(\"channel is full\")\n\n\t// errors when starting signal connection\n\tErrRequestChannelClosed       = errors.New(\"request channel closed\")\n\tErrCouldNotMigrateParticipant = errors.New(\"could not migrate participant\")\n\tErrClientInfoNotSet           = errors.New(\"client info not set\")\n)\n","sourceCodeStart":16,"sourceCodeEnd":37,"githubUrl":"https://github.com/livekit/livekit/blob/ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6/pkg/routing/errors.go#L16-L37","documentation":"ErrCouldNotMigrateParticipant is a sentinel in pkg/routing returned when a participant cannot be migrated from one node to another. Migration requires state transfer (offer/answer, tracks, ICE state) between the source and destination nodes; any failure in that handoff surfaces as this error. It groups underlying causes under a single well-known error for callers.","triggerScenarios":"Calling the participant migration path (during node drain or room rebalancing) when the target node cannot accept the participant, the source state cannot be serialized, or the handoff RPC fails.","commonSituations":"Node drain/maintenance while participants are connected; target node lost connectivity mid-migration; version mismatch between source and target nodes preventing state transfer; ICE/DTLS state already too far along to resume on another node.","solutions":["Allow the client to reconnect — most clients transparently rejoin and the session is re-established on the new node","Verify source and destination nodes run compatible LiveKit versions","Check network connectivity and psrpc health between the two nodes","Retry migration to a different target node, or defer drain until participants naturally leave"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// pre-check target node reachability before attempting migration\nif err := pingNode(targetNode); err != nil {\n    return fmt.Errorf(\"target node %s unreachable, pick another: %w\", targetNode.Id, err)\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, routing.ErrCouldNotMigrateParticipant) {\n    logger.Warnw(\"migration failed, falling back to client reconnect\", \"error\", err)\n    return allowClientReconnect(participant)\n}","preventionTips":["Keep source and destination nodes on compatible versions","Verify inter-node psrpc connectivity before drain","Migrate only participants whose ICE state permits resumption","Pick alternate targets and retry migration"],"tags":["routing","migration","multi-node","livekit"],"backgroundTag":"participant-migration-failed","analyzedSha":"ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6","analyzedAt":"2026-09-02T03:56:08.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}