>
Home5G NRRRC — Radio Resource ControlConditional HO & DAPS
🗂️ RRC — Radio Resource ControlAdvanced

Conditional Handover (CHO) & DAPS in 5G NR

Robust mobility — preparing candidate cells with execution conditions (CondEvent A3/A5) so the UE executes the handover itself, plus DAPS make-before-break.

📚 3GPP-basedTS 38.331TS 38.300

Baseline handover has two independent weaknesses, and Rel-16 attacked them separately. Conditional handover attacks fragility: in baseline handover both the measurement report and the handover command have to cross a radio link that is, by definition, getting worse, so the command frequently arrives too late or not at all. CHO breaks that dependency by delivering the command early -- several of them, one per candidate -- and letting the UE decide when to use one. DAPS attacks the interruption: even a flawless handover has tens of milliseconds during which the UE has no serving cell, and DAPS removes it by keeping the source link up and receiving while the target link is brought up. This document is the detail for both: conditionalReconfiguration and the CondEvents decoded, the resource cost at every prepared candidate, the late-forwarding problem and why EARLY STATUS TRANSFER exists, the DAPS dual stack down to which key deciphers which leg, the uplink switch, daps-SourceRelease, and a short treatment of Rel-18 LTM with a four-way comparison. The framework -- taxonomy, phases, reconfigurationWithSync, T304, MRO -- is in the companion 22 Handover Overview; the procedures these mechanisms modify are in 23 Xn Handover and 24 NG / N2 Handover.

Contents
  1. 01Two Different Weaknesses, Two Different Fixes
  2. 02CHO: the Dependency It Breaks
  3. 03conditionalReconfiguration, Field by Field
  4. 04CondEvent A3, A5 and A4: Same Inequality, Different Consumer
  5. 05Candidate Preparation, and What It Costs at Every Candidate
  6. 06Execution: the UE Decides, Alone
  7. 07Cancellation, the Remove List, and Stale Candidates
  8. 08Late Data Forwarding and EARLY STATUS TRANSFER
  9. 09CHO Failure Handling, and Trying Another Candidate
  10. 10DAPS: Removing the Interruption Instead of the Risk
  11. 11daps-Config: a Per-Bearer Decision
  12. 12The Dual Stack: Two MACs, Two RLCs, One PDCP
  13. 13Uplink Switching, and the Source After the UE Has Attached
  14. 14PDCP in DAPS: Reordering, Duplicates and Two Keys
  15. 15Source Release: How the Overlap Ends
  16. 16DAPS Constraints and Costs
  17. 17LTM (Rel-18): L1/L2-Triggered Mobility
  18. 18Baseline, CHO, DAPS and LTM Side by Side
  19. 19Failure Modes Across All Three Mechanisms
  20. 20Worked Arithmetic
  21. 21Illustrative Message Traces
  22. 22Release Deltas: Rel-15 to Rel-18
  23. 23Reading CHO and DAPS in Logs: A Checklist
  24. 24Glossary
  25. 25References

1. Two Different Weaknesses, Two Different Fixes

The companion 22 Handover Overview budgets a good NR handover at about 26 ms of user-plane interruption, and the companion 23 Xn Handover shows the procedure that produces it. Both documents describe a mechanism that works. Rel-16 added CHO and DAPS not because baseline handover is broken but because it has two distinct weaknesses that no amount of parameter tuning removes, and each enhancement removes exactly one of them.

Conditional handover (CHO)DAPS handover
The weakness it attacksThe handover command has to survive a link that is deteriorating. So does the measurement report that asked for it. Both are on the critical path at the worst possible moment.Even a perfect handover has an interval with no serving cell: the UE has released the source and has not yet been granted resources at the target.
What it changesThe command is delivered early, while the source link is still good, for several candidates at once. The UE decides when to use one.The source link stays up and keeps carrying data while the target link is established. There is no break to cover.
What it improvesRobustness. Handover failure rate and the tail of the interruption distribution -- not the mean.Interruption. Near-zero for the bearers configured for it -- and nothing else.
What it costsReserved context, a C-RNTI and usually a CFRA preamble at every prepared candidate, for the whole life of the configuration; late data forwarding; a cancellation message per unused candidate.A second concurrent protocol stack in the UE: two MAC entities, two RLC instances, and a PDCP entity that has to merge two legs with two different ciphering keys.
Gated by UE capabilitycondHandover and related fields in TS 38.306; widely supported.daps-HO in TS 38.306, with separate intra- and inter-frequency indications and power-sharing modes; far from universal.
ReleaseRel-16, extended in Rel-17 (CondEvent A4, conditional PSCell change) and Rel-18 (subsequent CHO)Rel-16, essentially unchanged since
Combinable with the otherNo -- see the callout belowNo -- see the callout below

Table 1. CHO and DAPS are not two attempts at the same thing. A network that measures only mean interruption will conclude CHO does almost nothing, and a network that measures only handover failure rate will conclude DAPS does almost nothing. Both conclusions are artefacts of the metric.

💡
Key point

CHO and DAPS cannot be combined. A condRRCReconfig must not carry daps-Config, and the network is not permitted to configure a DAPS handover as a conditional one TS 38.331 cl. 5.3.5.13 TS 38.300 cl. 9.2.3.5. The reason is structural rather than arbitrary: DAPS requires the source to keep serving the UE across the execution, which means the source has to know when execution happens so it can keep transmitting and later be released -- and the whole point of CHO is that the source does not know. The original short version of this document said the two combine; that is wrong for Rel-16 and Rel-17, and it is the single most common misconception about either feature.

One more mechanism belongs here even though it is a different release. LTM, Rel-18's L1/L2-triggered mobility, attacks both weaknesses at once by moving the switch decision out of RRC entirely: candidates are pre-configured, the switch command is a MAC CE, and execution can be RACH-less. Section 17 covers it, and §18 puts all four mechanisms on one page.

2. CHO: the Dependency It Breaks

Work through baseline handover as a sequence of things that can fail, in the order they happen, and one pattern stands out.

StepWhich link carries itState of that linkConsequence of losing it
UE enters event A3, sends MeasurementReportSource uplink, SRB1, RLC-AMDegrading -- A3 fires precisely because the serving cell is losing to a neighbourRLC retransmits, so the report is usually delivered eventually. "Eventually" costs tens of milliseconds of an already-late decision.
Source prepares the target over XnTransport networkHealthy, and irrelevant to the radioNone on the radio; §15 of the companion 23 Xn Handover covers this.
Source sends RRCReconfiguration with reconfigurationWithSyncSource downlink, SRB1, RLC-AMDegrading further -- 20 to 40 ms have elapsed since the reportThis is the failure that matters. If the command is not received, the UE has no idea a handover was intended. It stays on a dying cell until RLF, then re-establishes: hundreds of milliseconds, and MRO will classify it too late.
UE accesses the targetTarget uplink and downlinkGood, or the target would not have been chosenT304 expiry and re-establishment. Real, but much rarer than the row above.

Table 2. Four steps, and the two that are most likely to fail are the two carried on the source link at the moment it is worst. The third row is the dominant cause of too-late handover failures.

CHO's insight is that the third row does not have to be there. Nothing forces the command to be delivered at the moment of execution. If the network sends it while the source link is still comfortable and the UE stores it, the command has already survived the link before the link gets bad. Execution then costs no signalling at all: the UE applies something it already has.

That inverts the usual trade. Baseline handover delays the command until the last useful moment so that the decision is based on fresh measurements. CHO sends the command early and moves the decision to the moment of execution instead -- and because the decision is now made by the UE against its own live measurements, it is fresher than the network's could ever be. The original short version of this document put it well: the value is not that CHO cells are more reliable, it is that the decision is made much closer to the moment of execution.

Figure 1. Preparation. Note what does not happen at step 7: no T304 starts, no source is released, no RACH occurs. The UE has acknowledged a configuration it has been told to keep in a drawer.
💡
Key point

CHO does not shorten a successful handover by much -- about 8 ms of the 26 ms budget, because the stored configuration is already parsed (§20.1). It shortens the distribution. Comparing CHO to baseline on mean interruption understates it dramatically; compare handover failure rate, or the 99th percentile of interruption including recoveries. A trial that reports "CHO gave us 8 ms" measured the wrong thing.

🔍
What you see in logs

A UE that has a stored conditional reconfiguration and loses the source link entirely does not necessarily suffer a re-establishment. With attemptCondReconfig configured, the UE performing RRC re-establishment will, if the cell it selects is one of its stored candidates, apply that stored condRRCReconfig instead of sending RRCReestablishmentRequest TS 38.331 cl. 5.3.5.13. In a log this looks like an RLF followed immediately by an RRCReconfigurationComplete at a new cell with no re-establishment exchange at all -- which is startling the first time you see it, and is CHO working exactly as designed (§9).

3. conditionalReconfiguration, Field by Field

All of CHO on the air interface is one optional IE inside RRCReconfiguration, and its structure is worth reading closely because the nesting is where the design lives: each candidate carries a complete stored RRCReconfiguration, including its own reconfigurationWithSync and therefore its own target cell, its own C-RNTI and its own T304.

-- TS 38.331, abridged with `...` marking omitted fields and extension
-- markers. Rel-16 suffixes retained because they are what a decoder prints.

RRCReconfiguration-v1610-IEs ::= SEQUENCE {
    otherConfig-r16              OtherConfig-r16              OPTIONAL,
    bap-Config-r16               SetupRelease { BAP-Config-r16 } OPTIONAL,
    iab-IP-AddressConfigurationList-r16  ...                   OPTIONAL,
    conditionalReconfiguration-r16  ConditionalReconfiguration-r16 OPTIONAL,
    daps-SourceRelease-r16       ENUMERATED{true}             OPTIONAL,
    ...
}

ConditionalReconfiguration-r16 ::= SEQUENCE {
    attemptCondReconfig-r16      ENUMERATED {true}            OPTIONAL,
    condReconfigToRemoveList-r16 CondReconfigToRemoveList-r16 OPTIONAL,
    condReconfigToAddModList-r16 CondReconfigToAddModList-r16 OPTIONAL,
    ...
}

CondReconfigToRemoveList-r16 ::=
    SEQUENCE (SIZE (1..maxNrofCondCells-r16)) OF CondReconfigId-r16
CondReconfigToAddModList-r16 ::=
    SEQUENCE (SIZE (1..maxNrofCondCells-r16)) OF CondReconfigToAddMod-r16

CondReconfigToAddMod-r16 ::= SEQUENCE {
    condReconfigId-r16      CondReconfigId-r16,          -- INTEGER (1..8)
    condExecutionCond-r16   SEQUENCE (SIZE (1..2)) OF MeasId  OPTIONAL,
    condRRCReconfig-r16     OCTET STRING (CONTAINING RRCReconfiguration)
                                                             OPTIONAL,
    ...
}

maxNrofCondCells-r16  INTEGER ::= 8

-- and inside each stored condRRCReconfig, the ordinary machinery:
--   masterCellGroup -> CellGroupConfig -> spCellConfig
--                   -> reconfigurationWithSync
--                      { spCellConfigCommon, newUE-Identity, t304,
--                        rach-ConfigDedicated, ... }

Listing 1. The recursion is the point: condRRCReconfig is an RRCReconfiguration, so everything the companion 22 Handover Overview says about reconfigurationWithSync applies inside each candidate, independently.

FieldRange / typeTypical valueEffect, and what goes wrong
attemptCondReconfigENUMERATED {true}, optionalSet, in almost every deploymentTells the UE to try its stored candidates during RRC re-establishment instead of sending RRCReestablishmentRequest. Omitting it throws away most of CHO's robustness benefit while paying the entire resource cost.
condReconfigIdINTEGER (1..8)1, 2, 3 ...The handle for one candidate. Reused for modify; quoted in the remove list. It identifies a configuration, not a cell -- two ids can legitimately point at the same cell with different conditions.
condExecutionCond1 or 2 MeasId valuesOne measId for a CondEvent A3; two where an A3 and an A5 must both holdBoth listed conditions must be satisfied for execution -- it is an AND, not an OR TS 38.331 cl. 5.3.5.13. A measId pointing at a reportConfig that is not a condTriggerConfig is a configuration error the UE rejects, and the whole RRCReconfiguration fails.
condRRCReconfigOCTET STRING containing a full RRCReconfiguration150-400 bytes per candidateThe stored handover command, authored by that candidate's gNB and relayed by the source (companion 23 Xn Handover §6). Absent on a modify that only changes the condition.
condReconfigToRemoveList1..8 CondReconfigId--Cancels prepared candidates (§7). Its arrival is the only thing besides execution that frees the resources at the candidate.
maxNrofCondCells82 to 4 in practiceThe hard ceiling on stored candidates. Nothing stops a network using all 8; §20.3 is why almost nobody does.

Table 3. The whole air-interface configuration. Everything else about CHO is either measurement configuration (§4) or Xn signalling (§5).

📘
Spec detail

condExecutionCond is a list of one or two measId values, and where there are two the UE requires both. That is genuinely useful -- the canonical pairing is a CondEvent A3 (the neighbour is better than the serving cell by a margin) and a CondEvent A5 (the serving cell is below an absolute threshold and the neighbour is above one), which together mean "only move when the serving cell is actually in trouble and this neighbour is actually good". A single A3 will happily fire on a hilltop where both cells are strong, and that is where CHO ping-pong comes from.

⚠️
Common pitfall

Both condReconfigId and measId are small integers, and the measId values in condExecutionCond live in the same measIdToAddModList as ordinary reporting measurements (companion 20 Measurements and Events). A measConfig in the executed candidate's stored condRRCReconfig that removes a measId still referenced by another stored candidate is harmless only because execution discards the other candidates anyway. Before execution, though, a measIdToRemoveList that takes out a CondEvent measId silently disables the candidate that depended on it. It stays in the UE's stored set, holding resources at its target, and can never fire.

4. CondEvent A3, A5 and A4: Same Inequality, Different Consumer

CHO does not invent new measurement mathematics. A CondEvent A3 uses the same entry and leaving inequalities as the event A3 in the companion 20 Measurements and Events, with the same a3-Offset, the same hysteresis and the same timeToTrigger. What differs is who consumes the result: an ordinary A3 produces a MeasurementReport on SRB1, and a CondEvent A3 produces nothing on the air -- it satisfies a condition the UE is evaluating against its own stored candidate list.

-- TS 38.331, abridged. condTriggerConfig is a reportType alternative,
-- alongside periodical and eventTriggered.

ReportConfigNR ::= SEQUENCE {
    reportType  CHOICE {
        periodical            PeriodicalReportConfig,
        eventTriggered        EventTriggerConfig,
        reportCGI             ReportCGI,
        ...,
        reportSFTD            ReportSFTD-NR,
        condTriggerConfig-r16 CondTriggerConfig-r16,     -- CHO / CPAC
        ...
    }
}

CondTriggerConfig-r16 ::= SEQUENCE {
    condEventId  CHOICE {
        condEventA3  SEQUENCE {
            a3-Offset-r16       MeasTriggerQuantityOffset,
            hysteresis-r16      Hysteresis,
            timeToTrigger-r16   TimeToTrigger
        },
        condEventA5  SEQUENCE {
            a5-Threshold1-r16   MeasTriggerQuantity,   -- serving cell
            a5-Threshold2-r16   MeasTriggerQuantity,   -- neighbour
            hysteresis-r16      Hysteresis,
            timeToTrigger-r16   TimeToTrigger
        },
        ...,
        condEventA4-r17 SEQUENCE {
            a4-Threshold-r17    MeasTriggerQuantity,
            hysteresis-r17      Hysteresis,
            timeToTrigger-r17   TimeToTrigger
        }
    },
    ...
}

Listing 2. Note what CondTriggerConfig does not have: no reportAmount, no reportInterval, no reportQuantity, no maxReportCells. There is no report, so there is nothing to configure about one.

CondEvent A3CondEvent A5CondEvent A4 (Rel-17)
Entry conditionMn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + OffMp + Hys < Thresh1 and Mn + Ofn + Ocn - Hys > Thresh2Mn + Ofn + Ocn - Hys > Thresh
In wordsThis candidate is better than my serving cell by a3-OffsetMy serving cell is bad in absolute terms and this candidate is good in absolute termsThis candidate is good in absolute terms, whatever my serving cell is doing
Configured valuea3-Offset, -30 to +30 in 0.5 dB stepsa5-Threshold1 and a5-Threshold2, as RSRP/RSRQ/SINR rangesa4-Threshold
Typical CHO value6 to 10 dB -- deliberately larger than the 2 to 3 dB used for reporting A3Thresh1 around -110 dBm, Thresh2 around -100 dBm RSRPAround -100 dBm RSRP
What it is good forCoverage handover on a homogeneous layer. The default choice.Guarding against firing while the serving cell is still perfectly adequate. Usually paired with an A3.Inter-frequency and inter-layer moves, and conditional PSCell change, where a comparison against the serving cell is meaningless.
Failure signature if mis-setOffset too small: CHO fires almost immediately on configuration, producing ping-pong. Too large: the condition never fires and the UE rides the source into RLF.Thresh1 too permissive turns A5 into a no-op and you are back to a bare A3.A single absolute threshold on a loaded layer moves UEs to a cell that is strong but full.

Table 4. The three CondEvents. The inequalities are identical to the reporting events of the same names; only Off in the A3 form comes from a3-Offset inside CondTriggerConfig rather than from an EventTriggerConfig.

Figure 2. One drive-by, two candidates. Both neighbours cross the reporting threshold within 20 ms of each other, so a single report prepares both. The execution threshold is 7 dB higher, and the steeper riser reaches it 320 ms before the other -- which is the entire selection logic.
⚠️
Common pitfall

The reporting offset and the CHO offset do different jobs and should not be the same number. The reporting A3 offset decides when to prepare, and wants to be small so that preparation happens early, while the source link is still healthy. The CondEvent A3 offset decides when to move, and wants to be large enough that the UE does not move to a cell it will immediately want to leave. A deployment that copies its reporting offset into CondTriggerConfig gets candidates that qualify the instant they are configured -- and a UE that executes on receipt of the conditional reconfiguration is not doing CHO, it is doing a slow baseline handover with extra prepared cells.

💡
Key point

Both thresholds in the figure are curves, not levels: they track the serving cell. a3-Offset is a relative commitment. In a cell that is collapsing quickly, an A3-only condition will eventually be satisfied by every neighbour the UE can hear, including bad ones -- which is exactly the case an accompanying CondEvent A5 with an absolute a5-Threshold2 is there to stop.

5. Candidate Preparation, and What It Costs at Every Candidate

Preparation is the ordinary Xn handover preparation of the companion 23 Xn Handover, run once per candidate, with one Rel-16 addition: HANDOVER REQUEST carries a Conditional Handover Information Request IE that tells the target this is a candidate, not a commitment TS 38.423 cl. 9.1.1. The target's answer is the same HANDOVER REQUEST ACKNOWLEDGE, with the same transparent container carrying the same target-authored RRCReconfiguration. Everything the source relays to the UE is authored by the candidates.

Difference from baseline preparationWhere it appearsWhy it exists
The request is flagged conditionalConditional Handover Information Request IE in XnAP HANDOVER REQUESTThe target must not assume the UE is coming. It sizes its reservation, and its supervision timer, differently.
An estimated arrival probability may be suppliedInside the same IELets a target admit a low-probability candidate against a shared pool rather than a dedicated reservation. Purely advisory; the source's estimate is a guess.
The target's supervision timer is much longerTarget-side XnAP timer, in the TXnRELOCoverall familyA prepared CHO candidate may wait hundreds of milliseconds or seconds for a UE that may never come. A baseline-length timer would release the context before the condition fires.
Cancellation is an explicit procedureXnAP CONDITIONAL HANDOVER CANCEL, class 2 TS 38.423 cl. 8.2Baseline handover has HANDOVER CANCEL for a withdrawn preparation; CHO needs a cancellation per candidate and needs it to be routine rather than exceptional (§7).
The source is told when the UE arrivesXnAP HANDOVER SUCCESS, class 2, target to sourceIn baseline handover the source knows where the UE went because it chose. In CHO it does not, and forwarding cannot start until it is told (§8).
N preparations per handover, not oneN HANDOVER REQUEST / ACKNOWLEDGE pairs, N F1AP UE CONTEXT SETUPs at N targetsThere is no bulk form. Each candidate is a full context creation at a different gNB, including the CU/DU exchange of the companion 23 Xn Handover §9.

Table 5. CHO preparation against baseline preparation. Only the first two rows are new IEs; the rest are new procedures and new timer values, which is why a Rel-15 peer cannot participate.

5.1 What is actually reserved, per candidate

ResourceHeld atQuantity per candidateWhat exhausting it looks like
UE context (CU) and UE context (DU)Every candidate gNBOne gNB-CU UE F1AP ID, one gNB-DU UE F1AP ID, one XnAP UE ID pairPreparation starts failing with resource causes at cells that look lightly loaded on the air, because their contexts are full of UEs that are not there.
C-RNTICandidate DU, in the candidate cellOne 16-bit value, allocated at UE CONTEXT SETUP and unusable until cancelledRarely exhausted -- there are about 65 000 -- but it is a real accounting entry and it is why an unused candidate is not free.
CFRA preambleCandidate DUOne ra-PreambleIndex per SSB the UE might select, so often 2 to 4The one that runs out. 64 preambles per RACH occasion, of which typically 8 to 16 are set aside for contention-free use. See §20.3.
Admitted GBR capacityCandidate gNB admission controlThe guaranteed flow bit rate of every GBR flow in the UE's PDU sessionsHANDOVER PREPARATION FAILURE with no-radio-resources-available-in-target-cell from cells whose actual PRB utilisation is moderate.
Security contextCandidate gNBOne K_NG-RAN*, derived by the source from that candidate's PCI and downlink ARFCN, with the same NCCNot exhaustible, but note that N candidates means N distinct keys derived from one K_gNB with one NCC -- see the callout.
Forwarding tunnel endpointsCandidate gNBUsually not allocated until the UE actually arrives, precisely because CHO forwarding is late (§8)Not applicable; this is the resource CHO conspicuously does not pre-reserve.

Table 6. Per candidate, per UE, for the whole life of the conditional configuration. Multiply by the number of candidates and by the number of UEs in the overlap region before deciding that 8 candidates sounds generous.

📘
Spec detail

The source derives a separate K_NG-RAN* for every candidate, from the same K_gNB and the same NCC but with each candidate's own PCI and ARFCN as inputs TS 33.501 cl. 6.9.2. So the keys differ per candidate, and only the candidate the UE actually reaches ever uses its one; the others are discarded unused. This is fine cryptographically -- the derivation is bound to the target cell -- but it means the nextHopChainingCount in every stored condRRCReconfig is the same value, and a UE that executes at candidate 2 derives its key with the NCC it was given at configuration time, possibly hundreds of milliseconds earlier. See the companion 27 AS Security Mode.

⚠️
Common pitfall

A candidate gNB has no way to distinguish "this UE is coming" from "this UE is one of eight maybes" unless the source sets the conditional flag. Against a peer that does not implement it, the source has two bad options: prepare candidates as if they were commitments, in which case the target's short supervision timer releases them before the condition fires and execution arrives at a cell with no context; or do not use CHO on that neighbour relation. The first produces the most confusing failure in this document -- a PRACH on a reserved CFRA index arriving at a DU that has never heard of the UE.

6. Execution: the UE Decides, Alone

Execution is the part with no signalling in it. The UE evaluates each stored candidate's condExecutionCond at its ordinary measurement cadence; when a candidate's condition has held for its timeToTrigger, the UE selects that candidate, applies the stored condRRCReconfig, and from that instant behaves exactly as it would have on receiving a baseline handover command -- release the source, start T304, access the target TS 38.331 cl. 5.3.5.13.

Figure 3. The evaluation loop. The interesting arrow is the dashed one: "nothing happened, try again next period" is the state the UE is in for the overwhelming majority of a conditional configuration's life.
  1. Evaluate. For each stored condReconfigId, check every measId in its condExecutionCond. Where there are two, both must hold. Evaluation runs against the same layer-3 filtered measurements as ordinary reporting, so filterCoefficient applies here too (companion 20 Measurements and Events §6).
  2. Time the condition. The entry condition must hold continuously for timeToTrigger. A CHO timeToTrigger is usually shorter than the reporting one -- 40 to 80 ms against 160 to 320 ms -- because the whole point is to execute promptly once the condition is genuinely met.
  3. Select. If exactly one candidate qualifies, take it. If several qualify in the same evaluation, TS 38.331 does not mandate a rule: the choice is the UE's. Most implementations take the strongest, but you cannot rely on it, and two UE models in the same location can legitimately pick differently.
  4. Apply. Apply the selected candidate's stored condRRCReconfig as if it had just arrived on SRB1. This includes its masterCellGroup, its radioBearerConfig, its masterKeyUpdate and its reconfigurationWithSync.
  5. Start that candidate's T304. Each stored configuration carries its own t304 inside its own reconfigurationWithSync, and it starts now -- not at configuration time. Two candidates may carry different T304 values because they were authored by different gNBs.
  6. Release the source and access the target. MAC reset, source C-RNTI discarded, retune, RACH at the selected target using the CFRA preamble that candidate allocated (companion 03 Random Access).
  7. Discard everything else. On successful completion the UE releases the entire stored conditional reconfiguration -- all candidates, including the one it used. There is no residue, which is why a Rel-16 UE cannot chain one CHO execution into the next (§22).
Figure 4. Execution and its aftermath. The UE is fully served by the new cell before the source has been told anything -- so steps 4 to 6 are pure catch-up, and every millisecond of them is added to the interruption of the forwarded data.
📘
Spec detail

T304 in a CHO does not supervise the wait for the condition. Nothing does. A UE can hold a conditional reconfiguration for as long as the network leaves it configured, evaluating quietly, with no timer running and no signalling. That is why the resource cost in §5.1 is open-ended, and why the network -- not the UE -- must eventually clean up (§7).

🔍
What you see in logs

Because the source is not involved, there is no source-side log line for a CHO execution. The source's first indication is XnAP HANDOVER SUCCESS arriving from a candidate, typically 30 to 60 ms after the UE has actually gone. In a source-side log a CHO execution therefore looks like: uplink from the UE simply stops, nothing is logged for tens of milliseconds, then HANDOVER SUCCESS appears naming one of the candidates. If you are trying to establish when the UE executed, the only reliable witness is the chosen target's PRACH timestamp.

7. Cancellation, the Remove List, and Stale Candidates

A prepared candidate that is never used has to be dismantled in two places: at the UE, where the stored configuration would otherwise keep being evaluated, and at the candidate gNB, where the context and the reserved resources of §5.1 sit idle. The two are separate mechanisms and either can be skipped.

What is being cleaned upMechanismWho initiatesWhat happens if it is skipped
The stored configuration at the UEcondReconfigToRemoveList in a later RRCReconfiguration, listing the condReconfigId values to dropThe source gNB, on its own judgement -- typically because the candidate's measurements have collapsed, or the UE has moved out of the regionThe UE keeps evaluating a candidate whose target no longer has a context for it. If the condition later fires, the UE executes into nothing: PRACH at a cell that does not know it, T304 expiry, re-establishment.
The stored configuration at the UE, implicitlySuccessful execution of any candidate discards all of them; so does leaving RRC_CONNECTEDThe UE, automaticallyNothing -- this path is reliable. It is the reason most stale candidates resolve themselves eventually.
The reserved context at an unused candidate gNBXnAP CONDITIONAL HANDOVER CANCEL, class 2, with a CauseThe source, on learning from HANDOVER SUCCESS which candidate won -- or on deciding to remove a candidateThe candidate holds a C-RNTI, a CFRA preamble and admitted capacity until its own supervision timer expires. That timer is deliberately long for CHO (§5), so the leak is long.
The reserved context, as a backstopTarget-side supervision timer expiryThe candidate gNBThis is the backstop, so nothing -- but it is the slow path, and a source that never cancels is relying on it for every candidate of every handover.

Table 7. Four clean-up paths. Only the second is automatic and reliable; the first and third are things a source gNB has to remember to do, and the fourth is a timer measured in seconds.

⚠️
Common pitfall

This is the failure mode that scales badly. One source gNB that does not send CONDITIONAL HANDOVER CANCEL is invisible in its own logs -- its handovers all succeed -- and shows up at its neighbours as elevated context occupancy and CFRA preamble pressure. The diagnostic is a count, per gNB, of prepared conditional candidates against (executions + cancellations + timer expiries). A persistent gap that is closed only by timer expiries is a source that is not cancelling, and the cell that suffers is not the cell with the bug.

There is also a genuinely benign version of the same signature. A UE that stops at the edge of a coverage overlap and stays there will hold its candidates for as long as it is stationary, and none of them is stale in any meaningful sense. Distinguishing the two requires looking at whether the candidate's measurements are still plausible, which is why implementations refresh condReconfigToAddModList periodically rather than configuring once and forgetting.

🔄
Release delta

A condReconfigToAddModList entry with the same condReconfigId as an existing one is a modify, and it may carry only condExecutionCond -- adjusting the threshold of an already-prepared candidate without re-preparing it over Xn, and without re-sending the 150-400 byte condRRCReconfig. This is the cheap way to retune a CHO trigger in flight, and it is what a well-implemented source does when the candidate is still good but the condition is proving too eager.

8. Late Data Forwarding and EARLY STATUS TRANSFER

Here is CHO's real cost, and it is a user-plane cost rather than a signalling one. In a baseline Xn handover the source knows the target because it chose the target, so it can send SN STATUS TRANSFER and start forwarding within a millisecond or two of transmitting the handover command (companion 23 Xn Handover §11 and §12). In CHO the source does not know which candidate the UE picked until the candidate tells it. Everything downstream of that knowledge is late.

Baseline Xn handoverCHO
When the source learns the targetWhen it decides -- before the command is even sentWhen XnAP HANDOVER SUCCESS arrives from the chosen candidate, i.e. after the UE has already completed random access there
When SN STATUS TRANSFER can be sentImmediately after the command, ~1 msOnly after HANDOVER SUCCESS -- typically 30 to 60 ms after execution
When forwarding startsImmediately after SN STATUS TRANSFER; forwarded data is often waiting at the target before the UE arrivesAfter HANDOVER SUCCESS. The target is already scheduling the UE and has nothing to send it.
Size of the source's buffer at that momentOne command-to-arrival interval of downlink data, ~25 ms worthOne command-to-arrival interval plus the HANDOVER SUCCESS round trip, so 50 to 90 ms worth -- and the whole time, PDCP discardTimer is expiring on the oldest of it
Effect on the interruptionStep h of the budget: 1 to 2 msStep h becomes 3 to 6 ms, and the first forwarded PDU can be much later than that (§20.1)
MitigationNone neededEARLY STATUS TRANSFER -- send the downlink COUNT to every candidate in advance

Table 8. The same procedure, one piece of missing knowledge, and a measurably worse user plane. This is the trade CHO makes for its robustness.

8.1 What EARLY STATUS TRANSFER is for

Ordinary SN STATUS TRANSFER has a hard ordering constraint: it conveys the next downlink PDCP SN the source would have assigned, which means the source must have stopped assigning them. It cannot be sent early without stopping the downlink early, which would lengthen the interruption for nothing. Rel-16 breaks that coupling with a separate class 2 procedure TS 38.423 cl. 8.2.

IEContentsWhat the receiver does with it
Source / Target NG-RAN node UE XnAP IDThe usual correlation pairMatches the message to a prepared context. A candidate that has already been cancelled discards it.
Procedure Stage: First DL COUNTPer DRB, the COUNT (HFN and PDCP SN) of the first downlink SDU the target should transmitSets the target's downlink numbering start so it can begin numbering and transmitting the instant it has anything to send, without waiting for the source's final state.
Procedure Stage: DL discarding (Rel-17)Per DRB, a COUNT up to which the target should discard forwarded dataLets the source tell the target that data it already forwarded has since been delivered on the source leg -- the DAPS case (§15) and the Rel-17 CHO forwarding optimisation.
DRBsSubjectToEarlyStatusTransfer-ListOne entry per DRB, so the granularity matches SN STATUS TRANSFERA DRB absent from the list gets no early numbering and behaves as it would without the feature.

Table 9. EARLY STATUS TRANSFER, abridged. The Rel-17 DL discarding stage is the one that makes the message useful for DAPS as well as for CHO.

💡
Key point

EARLY STATUS TRANSFER does not solve CHO's forwarding problem; it narrows it. The target can now start numbering early, but the source still cannot send it any data until it knows the UE went there -- forwarding N candidates' worth of the same downlink buffer to N different gNBs would multiply the Xn load by N and deliver duplicates to N-1 cells that discard them. So the residual cost stands: CHO forwarding starts late, and the fix is to shorten the HANDOVER SUCCESS round trip, not to pre-forward.

🔍
What you see in logs

If you see both EARLY STATUS TRANSFER and SN STATUS TRANSFER for one UE, you are looking at CHO or DAPS, not baseline handover -- the two messages together are the reliable signature of a Rel-16 mobility enhancement in an Xn trace. EARLY STATUS TRANSFER to several peer gNBs for the same UE narrows it to CHO. A single peer, with the source continuing to transmit afterwards, narrows it to DAPS.

9. CHO Failure Handling, and Trying Another Candidate

Once the UE has executed, the failure handling is ordinary handover failure handling: T304 expires, the UE reverts to the source configuration if it can and initiates RRC re-establishment (companion 22 Handover Overview §8, companion 16 RLM and RLF). CHO adds one thing to that path, and it is the most valuable single line of configuration in the feature.

With attemptCondReconfig set, a UE that is performing RRC re-establishment and whose cell selection lands on a cell that is the target of one of its stored candidates applies that stored condRRCReconfig directly, instead of sending RRCReestablishmentRequest TS 38.331 cl. 5.3.5.13. It skips the whole re-establishment exchange -- no request, no RRCReestablishment with a fresh NCC, no RRCReestablishmentComplete, no SRB1-only intermediate state, no context fetch over Xn.

Recovery pathTriggerWhat the UE sends firstApproximate costPrerequisite
Second candidate via attemptCondReconfigT304 expiry at the first candidate, or RLF on the source before any executionPRACH at the second candidate with its CFRA preamble, then RRCReconfigurationCompleteOne T304 duration plus one access -- so about 100 + 20 ms from the point of failureattemptCondReconfig set, the selected cell is a stored candidate, and that candidate's context still exists at its gNB
Ordinary re-establishment to a prepared candidateSame, but attemptCondReconfig not setRRCReestablishmentRequest on SRB0T304 plus 60 to 150 ms of re-establishment, plus SRB2 and DRB resumptionThe target has, or can fetch, the UE context
Ordinary re-establishment elsewhereCell selection lands on a cell that is not a candidateRRCReestablishmentRequest on SRB0Same as above, plus a context fetch over XnA prepared or fetchable context somewhere
RRC setup from scratchNo context available anywhere -- RRCSetup in response to the re-establishment attemptRRCSetupRequestHundreds of milliseconds, plus NAS service request; every DRB is torn down and rebuiltNone -- this is the floor

Table 10. Four recoveries in descending order of desirability. The first exists only for CHO, and the gap between it and the second is the reason attemptCondReconfig is worth setting even in deployments that never see a CHO failure.

9.1 Timers around CHO and DAPS

TimerWhere it runsRange / typicalStarted byExpiry consequence
T304UE, one instance per executed handoverms50..ms10000; ms100 in FR1, ms150 in FR2Applying a reconfigurationWithSync -- for CHO, the stored one, at executionRevert to the source configuration if possible; RRC re-establishment, with the attemptCondReconfig shortcut above.
timeToTrigger (CondEvent)UE, per candidate conditionms0..ms5120; 40 to 80 ms for CHOThe entry condition becoming trueNot an expiry -- elapsing is what causes execution. Interrupted if the condition stops holding.
TRELOCprepSource gNB, per candidate preparationImplementation; commonly 100 msSending XnAP HANDOVER REQUESTThat candidate is abandoned. With CHO the source simply prepares fewer candidates and carries on -- it does not fail the handover.
TXnRELOCoverall familyCandidate gNB, per prepared contextImplementation; much longer for CHO -- seconds rather than hundreds of millisecondsSending HANDOVER REQUEST ACKNOWLEDGEThe prepared context and its C-RNTI, CFRA preamble and admitted capacity are released. This is the backstop for a source that never cancels (§7).
t-Reordering (PDCP)UE and gNB, per DRBms0..ms3000; 50 to 100 ms typicalA PDCP reordering gapIn DAPS this is what bounds how long the common PDCP entity waits for a straggler from the source leg (§14). Too short and the source leg's in-flight data is discarded, which undoes DAPS.
discardTimer (PDCP)gNB, per DRBms10..ms1500 / infinity; ms100 typicalA downlink SDU arriving at PDCPThe SDU is discarded and never forwarded. In CHO the forwarding delay of §8 means more SDUs hit this than in baseline handover.

Table 11. Timers that matter to these two features. Only T304 and the PDCP timers are specified with ranges in TS 38.331; the XnAP timers are implementation choices that TS 38.423 names but does not bound.

🔍
What you see in logs

The most common CHO-specific failure is not a radio failure. It is execution into a candidate whose context has already been released -- because the source removed the candidate at the UE but not at the gNB, or the other way round, or the candidate's supervision timer expired while the UE was still evaluating it. The signature at the candidate is unambiguous: a PRACH on a reserved CFRA index with no matching UE context. In a baseline handover that would mean the target gave up too early; in CHO it usually means the source and the candidate disagree about whether the candidate is still prepared.

10. DAPS: Removing the Interruption Instead of the Risk

DAPS starts from a different complaint. Suppose every handover succeeded first time, every command arrived, every target admitted every bearer. There would still be an interval -- about 26 ms in the budget of the companion 22 Handover Overview -- in which the UE has released the source and cannot yet be scheduled at the target. That interval is inherent to break-before-make, and no amount of robustness work removes it, because it is not a failure. It is the design.

Two thirds of it is not radio, either. Ten milliseconds is the UE's RRC processing allowance and five is the mean wait for a PRACH occasion. A faster physical layer does not help. The only way to remove the interval is to not have it: keep the source link up and receiving while the target link is established, and switch when the target is demonstrably working. That is make-before-break, and DAPS is its implementation.

Break-before-make (baseline, CHO)Make-before-break (DAPS)
Source link at executionReleased immediately on applying the reconfiguration -- before the UE has looked at the target even onceKept up. MAC is not reset, RLC is not re-established, the C-RNTI is retained.
Number of active MAC entitiesOne, alwaysTwo, for the duration of the overlap
Downlink during the transitionNothing -- no serving cellContinues on the source until the source is released, then continues on the target. Both legs may deliver simultaneously.
Uplink during the transitionNothingOn the source until random access at the target completes, then on the target. A hard switch, at one point in time (§13).
What ends the transitionThe UE getting a grant at the targetAn explicit RRCReconfiguration from the target carrying daps-SourceRelease (§15)
Applies toThe whole UEIndividual DRBs -- daps-Config is per bearer, and the rest of the UE's bearers get the ordinary break (§11)
Interruption for the bearers it covers26 ms typical, 68 ms worst case without a failureAbout 1 ms -- the uplink switch instant -- and 0 ms in the downlink

Table 12. The two patterns. Every row after the first follows from it: keeping the source means keeping a second MAC, a second RLC, and a PDCP entity that has to cope with two sources of the same bearer.

Figure 5. Baseline, CHO and DAPS on one axis, with a fourth lane for the bearer on the same DAPS handover that was not configured for DAPS. The fourth lane is the row everyone forgets: DAPS is not a property of the handover, it is a property of the bearer.
💡
Key point

DAPS removes the interruption and does nothing at all for robustness. If the handover command is lost on the degrading source downlink, DAPS cannot help -- the UE never learns a handover was intended, exactly as in baseline handover. If the target access fails, T304 expires and the UE re-establishes, exactly as in baseline handover, except that in DAPS it can fall back to a source link that is still up, which is a real but narrow benefit. CHO and DAPS are complements that Rel-16 does not let you combine (§1).

11. daps-Config: a Per-Bearer Decision

The single most consequential fact about DAPS is that it is configured per DRB, as an optional flag inside each DRB-ToAddMod entry of RadioBearerConfig. A DAPS handover is therefore not a mode the UE is in; it is a set of bearers that behave one way while the rest behave another, during one handover.

-- TS 38.331, abridged. daps-Config is a Rel-16 extension to the
-- per-DRB structure, not to the per-UE one.

RadioBearerConfig ::= SEQUENCE {
    srb-ToAddModList         SRB-ToAddModList         OPTIONAL,
    srb3-ToRelease           ENUMERATED{true}         OPTIONAL,
    drb-ToAddModList         DRB-ToAddModList         OPTIONAL,
    drb-ToReleaseList        DRB-ToReleaseList        OPTIONAL,
    securityConfig           SecurityConfig           OPTIONAL,
    ...
}

DRB-ToAddMod ::= SEQUENCE {
    cnAssociation            CHOICE { eps-BearerIdentity INTEGER (0..15),
                                      sdap-Config        SDAP-Config } OPTIONAL,
    drb-Identity             DRB-Identity,            -- INTEGER (1..32)
    reestablishPDCP          ENUMERATED{true}         OPTIONAL,
    recoverPDCP              ENUMERATED{true}         OPTIONAL,
    pdcp-Config              PDCP-Config              OPTIONAL,
    ...,
    [[ daps-Config-r16       ENUMERATED{true}         OPTIONAL ]]
}

-- and, in the same message, the uplink power split for the overlap:

ReconfigurationWithSync ::= SEQUENCE {
    spCellConfigCommon       ServingCellConfigCommon  OPTIONAL,
    newUE-Identity           RNTI-Value,
    t304                     ENUMERATED {ms50, ms100, ms150, ms200,
                                         ms500, ms1000, ms2000, ms10000},
    rach-ConfigDedicated     CHOICE { uplink, supplementaryUplink } OPTIONAL,
    ...,
    [[ smtc                  SSB-MTC                  OPTIONAL ]],
    [[ daps-UplinkPowerConfig-r16  DAPS-UplinkPowerConfig-r16 OPTIONAL ]]
}

DAPS-UplinkPowerConfig-r16 ::= SEQUENCE {
    p-DAPS-Source-r16        P-Max,                   -- dBm, -30..33
    p-DAPS-Target-r16        P-Max,
    uplinkPowerSharingDAPS-Mode-r16
        ENUMERATED { semi-static-mode1, semi-static-mode2, dynamic }
}

Listing 3. Two IEs and one flag. daps-Config per DRB says which bearers keep the source; DAPS-UplinkPowerConfig says how the UE splits its transmit power while it is talking to two cells.

FieldRangeTypicalEffect and consequence
daps-ConfigENUMERATED {true}, per DRB-ToAddModSet on one or two DRBsMakes that DRB a DAPS bearer: PDCP becomes a two-leg entity, a second RLC and the source RLC both feed it, and the source keeps transmitting on it. Absent means the DRB behaves as a baseline handover bearer and takes the full interruption.
p-DAPS-SourceP-Max, -30 to 33 dBmAround half the UE's maximum, in linear termsThe uplink power ceiling on the source leg during the overlap. Too generous and the target leg cannot reach; too mean and the source link drops before the release arrives.
p-DAPS-TargetP-Max, -30 to 33 dBmComplementary to the aboveSame, for the target leg. The two together must respect the UE's total power class.
uplinkPowerSharingDAPS-Modesemi-static-mode1, semi-static-mode2, dynamicsemi-static-mode1 is the common floor; dynamic needs UE supportHow the split is enforced. Semi-static modes hold a fixed split for the overlap; dynamic lets the UE reallocate per slot, which is better for throughput and harder to implement.
t304 in the stored / delivered reconfigurationWithSyncms50..ms10000ms100Unchanged in meaning, but its expiry is much less damaging in DAPS: the source link is still up, so the UE has somewhere to fall back to (§19).

Table 13. The DAPS parameter set. Note that the interesting configuration is about power, not about the protocol: transmitting to two cells at once is the physical constraint DAPS actually runs into.

⚠️
Common pitfall

The per-bearer choice is a real engineering decision and it is frequently made backwards. In the traces of §21 the network puts daps-Config on DRB 1, a 5QI 9 best-effort bearer, and leaves DRB 2, a 5QI 1 voice bearer, as an ordinary bearer -- so the TCP session that would have recovered from a 26 ms gap on its own gets protected, and the voice call that produces an audible artefact does not. That configuration exists in the wild, usually because DAPS was enabled on the default bearer first and never revisited. If a UE supports DAPS on only one DRB, spend it on the bearer whose users can hear the gap.

🔍
What you see in logs

There is no per-UE DAPS switch to look for in a trace. If you want to know whether a handover was a DAPS handover, the only reliable test is to decode radioBearerConfig in the handover command and look for daps-Config-r16 on at least one DRB-ToAddMod. A second, weaker signature is the absence of a MAC reset and the retention of the source C-RNTI at execution -- visible in a UE-side or DU-side log but not in the RRC message itself.

12. The Dual Stack: Two MACs, Two RLCs, One PDCP

"Dual active protocol stack" is precise about what is duplicated and what is not. Everything that is cell-specific is duplicated: two MAC entities with separate HARQ, separate scheduling, separate timers and separate C-RNTIs; two RLC entities with separate sequence-number spaces and separate ARQ state. Everything that is bearer-specific is single: one PDCP entity, one sequence-number space, one reordering window, one SDAP entity above it.

Figure 6. The waist is PDCP, and it is where all the difficulty lives. Below it, two entirely independent stacks that do not know about each other. Above it, an application that never learns a handover happened.
LayerHow many during the overlapState that is separateWhy it has to be that way
SDAPOne--SDAP maps QoS flows to DRBs. The DRB is the same DRB throughout; only the cells underneath it change.
PDCPOneNothing is duplicated except the security and header-compression functions inside it (§14)The PDCP sequence number is what guarantees in-order, duplicate-free delivery. Two PDCP entities would mean two SN spaces and no way to order or deduplicate across the switch -- which is the entire problem DAPS is solving.
RLCTwoSN space, transmit and receive windows, ARQ and status reporting, t-Reassembly, segmentation stateRLC is per-cell-group by construction: it segments to a MAC grant from one scheduler and retransmits against acknowledgements from one peer. A shared RLC across two cells is not expressible.
MACTwoC-RNTI, HARQ entity and all its processes, BSR and PHR state, DRX state, timing advance, sr-ProhibitTimerTwo independent schedulers issue independent grants against independent HARQ feedback. Nothing here can be shared.
PHYTwoSync, AGC, beam management, TA loopThis is where the hardware cost is: the UE needs enough RF and baseband to receive two cells and transmit to one at a time within its power budget (§16).

Table 14. What is duplicated and why. Read the PDCP row twice -- the single PDCP entity is the whole architecture, and §14 is what it costs.

🔍
What you see in logs

In a UE-side or DU-side log the dual stack is visible as two simultaneously active C-RNTIs for one UE, which in any other context would be a bug. In the traces of §21 the UE holds C-RNTI 0x4C21 in PCI 231 and C-RNTI 0x6B14 in PCI 419 at the same time, is receiving PDSCH in both, and has two independent HARQ entities with two independent retransmission timelines. Correlating a UE across the overlap therefore needs the bearer identity, not the C-RNTI.

14. PDCP in DAPS: Reordering, Duplicates and Two Keys

One PDCP entity, two RLC entities beneath it, both delivering PDUs of the same bearer from the same sequence-number space. Three things follow, and the third is the subtle one.

14.1 Reordering across two legs

The receiving PDCP entity reorders on the single PDCP SN exactly as it always does, using t-Reordering and the RX_DELIV / RX_NEXT window of TS 38.323 cl. 5.2.2. The novelty is that a gap in the window may be filled from either leg, and the two legs have wildly different latency: the source leg is delivering data that has been in flight over the air, the target leg is delivering data that came over Xn-U and was numbered from an EARLY STATUS TRANSFER COUNT. A window that is too small, or a t-Reordering that is too short, discards source-leg stragglers and reintroduces exactly the gap DAPS removed.

14.2 Duplicate discard

Duplicates are expected, not exceptional. The source forwards SDUs it is not sure the UE received; the UE retransmits uplink SDUs the source may already have; the target may deliver a forwarded SDU that the source also managed to deliver over the air. PDCP's ordinary duplicate detection on COUNT handles all of it, which is the reason the single-entity design is not negotiable.

14.3 Two ciphering keys, and how PDCP knows which to use

The source leg is ciphered with the key set derived from the source's K_gNB; the target leg with the key set derived from K_gNB*, the fresh key the source computed from the target's PCI and ARFCN TS 33.501 cl. 6.9.2. They are different keys, they may even use different algorithms, and both are in use simultaneously on one bearer.

Figure 8. The whole difficulty in one header. There is no leg identifier, no key identifier and no cell identifier here -- so the association between a PDU and its key is entirely implicit in which RLC entity handed it up.
💡
Key point

This is the DAPS subtlety worth remembering. Nothing in the PDCP header says which cell a PDU came from. The common PDCP entity selects the deciphering key, the integrity key and the header-decompression instance purely from which RLC entity delivered the PDU. Consequently a PDU that is delivered on the wrong leg -- or an implementation that attaches the key to the bearer rather than to the leg -- deciphers to garbage. And because the PDCP SN was already read (it is not ciphered) the entity happily places that garbage in its reordering window at the correct position and delivers it upward. The symptom is not a handover failure and not a gap: it is a handover that succeeds while a burst of in-order, correctly numbered rubbish is delivered to the application, typically visible as a TCP checksum failure storm confined to the overlap window.

PDCP functionSingle-entity? Per leg?Consequence
Sequence numbering (TX_NEXT)YesNoOne SN space across the switch -- the precondition for in-order delivery.
Reordering (RX_DELIV, RX_NEXT, t-Reordering)YesNoGaps can be filled from either leg; the window must tolerate the latency difference between them (§14.1).
Duplicate discardYesNoHandles forwarded-and-also-delivered SDUs without any special DAPS logic.
Ciphering and decipheringNoYesTwo key sets in simultaneous use, selected by the delivering RLC entity. The failure mode above.
Integrity protection and verificationNoYesSame selection problem. A mis-selected key gives a MAC-I failure, which is at least loud, unlike the ciphering case.
Header compression (ROHC / EHC)NoYesTwo independent compressor and decompressor contexts, because the target has not seen the source's context. Compression efficiency dips during the overlap while the target's context is built up.
Discard timerYesNoOne discardTimer per SDU, running from arrival, regardless of which leg eventually carries it.

Table 16. The internal split of a DAPS PDCP entity TS 38.323 cl. 4.2. Everything that is about ordering is shared; everything that is about the cell is duplicated -- and the second group is the group with the security in it.

15. Source Release: How the Overlap Ends

The overlap does not time out and the UE does not end it. It ends because the target sends the UE an RRCReconfiguration containing daps-SourceRelease, on the target's SRB1, ciphered with the target's keys. It is an ordinary reconfiguration with one extra flag, and it is the only thing that ends the dual-connection period.

StepWhat happensWhere you see it
The target decides the overlap can endTypically when it has received SN STATUS TRANSFER and the End Marker from the source, so it knows there is nothing left in flight that only the source leg can deliverImplementation policy; not visible on any interface
RRCReconfiguration with daps-SourceReleaseSent on the target's SRB1. The UE does not need to be told which source to release -- it has only one.Target-side RRC log; a DL-DCCH message with daps-SourceRelease-r16 present and often nothing else
The UE releases the source stackSource MAC entity released (HARQ flushed, source C-RNTI discarded), source RLC entities released, source security keys and source ROHC context releasedUE-side log, and the disappearance of the UE from the source DU's scheduler
PDCP is reconfigured to one legThe entity stops being a DAPS PDCP entity: one key set, one header compression context, one RLC below it. The SN space and the reordering window are not reset -- that is the point.Nothing on any interface; this is internal to the UE and the target
RRCReconfigurationCompleteOn the target's SRB1Target-side RRC log
The source context is torn downXnAP UE CONTEXT RELEASE from the target, then F1AP UE CONTEXT RELEASE inside the source gNBXn and F1 traces, as in the companion 23 Xn Handover §13

Table 17. Six steps, of which only two put anything on an interface. The fourth row is the one that makes DAPS lossless: PDCP state survives the release untouched.

📘
Spec detail

The release comes from the target, not the source, and that trips people up when reading a trace. It has to: by the time the release is safe to send, the UE's SRB1 is anchored at the target, and the source has no reliable way to reach it. So the message that says "stop using the source" travels over the target's air interface, and if you are looking for it in the source cell's RRC log it is not there.

⚠️
Common pitfall

There is a timing hazard worth understanding. The target should not send daps-SourceRelease until it can deliver everything the source could -- which means after SN STATUS TRANSFER and the forwarded backlog. A target that releases early creates a hole: SDUs that were in flight on the source leg are lost, the UE's PDCP reordering window stalls on the missing SNs, and t-Reordering expires before the target's forwarded copies arrive. The result is a DAPS handover with a worse gap than a baseline handover would have had, and it is the single most common way to implement DAPS badly.

16. DAPS Constraints and Costs

DAPS is expensive in the UE and constrained in ways that limit where it can be deployed at all. None of this is a defect; it is the price of two simultaneous stacks in a battery-powered device.

ConstraintWhere it comes fromPractical consequence
UE capability gateddaps-HO and related fields in TS 38.306, with separate indications for intra-frequency and inter-frequency DAPS, for the number of supported DAPS bearers, and for the uplink power-sharing modes the UE can doA network cannot assume DAPS. It must read the capability (companion 26 UE Capability) and fall back per UE. In a mixed fleet the majority of handovers are still baseline.
Not combinable with CHOTS 38.331 cl. 5.3.5.13 / TS 38.300 -- a condRRCReconfig must not contain daps-ConfigYou choose robustness or interruption for a given handover, not both (§1).
Only a subset of DRBsdaps-Config is per DRB, and UE capability bounds how many DAPS bearers can be activeSome of the UE's traffic always takes the ordinary interruption. Pick the bearers deliberately (§11).
Frequency relationshipIntra-frequency DAPS is the well-supported case; inter-frequency requires separate capability and, in practice, a second receive chainDAPS is mostly a coverage-handover tool on one carrier. It is not the answer for inter-layer or inter-band mobility.
Uplink power sharingDAPS-UplinkPowerConfig; the UE has one power budget and two cells that both want uplinkAt cell edge -- which is where handovers happen -- splitting power means neither link gets what it wants. This bounds DAPS's usefulness at exactly the geometry it was built for.
Carrier aggregation restrictionsTwo active cell groups consume the RF and baseband resources that secondary cells would useExpect SCells to be released for the overlap. A DAPS handover on a heavily aggregated UE trades peak throughput for continuity.
RF and baseband costTwo receive chains active, two independent HARQ engines, two RLC instances, doubled PDCP security processingMeasurable current draw during the overlap, and silicon area all the time. This is why device support has stayed patchy.
No help with robustnessStructural -- see §10DAPS does not reduce handover failure rate. Deployments that enabled DAPS to fix a drop problem were solving the wrong equation.

Table 18. Eight constraints. The fifth and the last are the ones that most often decide against DAPS in a real deployment.

💡
Key point

The measured benefit is exactly what the mechanism promises and no more: near-zero interruption on the DAPS-configured DRBs, and the ordinary 26 ms on everything else the UE is carrying. If a DAPS trial reports a disappointing improvement in end-user experience, check which bearer the application was on before concluding the feature does not work. §20.1 puts numbers on the mixed case.

17. LTM (Rel-18): L1/L2-Triggered Mobility

CHO and DAPS both leave the procedure intact: an RRC reconfiguration is still applied, random access is still performed, an RRC message still completes the move. Rel-18's L1/L2-triggered mobility removes the RRC procedure from the critical path altogether. The candidate configurations are supplied in advance, and the actual cell switch is commanded by a MAC CE -- one downlink transmission the UE acts on in a few slots, with no RRC decode, no reconfiguration, and optionally no random access at all.

ElementWhat it isWhy it lowers the latency
Pre-configured candidate cellsThe ltm-Config structures in RRCReconfiguration carry a set of candidate cell configurations, each with an identifier, delivered and applied to the extent possible well before any switchThe 10 ms RRC processing allowance -- the largest single item in the baseline budget -- is spent in advance. At switch time the configuration is already resident and validated.
L1 measurement and reporting on candidatesThe UE reports L1-RSRP on candidate cells' reference signals through the CSI reporting framework, not through RRC MeasurementReportL1 reporting is periodic and fast -- milliseconds, against the tens to hundreds of milliseconds an L3 filtered report plus timeToTrigger takes. The network's picture is far fresher.
A MAC CE (or DCI) as the switch commandAn LTM Cell Switch Command MAC CE TS 38.321 naming which pre-configured candidate to activate, together with the TCI state to applyOne MAC transmission, HARQ-protected, acted on within a few slots. No RRC transaction, no RRCReconfigurationComplete on the critical path.
TCI-state-based switchingThe switch is expressed as a change of the active TCI state -- the same machinery beam management already uses -- pointing at the new cell's reference signalsThe UE already knows how to retune a TCI state quickly, and it already has the candidate's timing and beam information from its L1 measurements. Fine synchronisation is largely pre-done.
Early TA acquisition and RACH-less executionThe network can have the UE obtain a timing advance for a candidate before the switch, via a PDCCH-ordered random access to that candidate; the switch itself then needs no PRACHRemoves steps d, e and f of the baseline budget -- the PRACH occasion wait, the preamble and the RAR window -- which is 8 to 14 ms.
Scope in Rel-18Serving cell change within one DU / one CU, i.e. intra-gNB; inter-gNB mobility still needs an RRC handoverThe candidate configurations and the L1 reporting only make sense where one scheduler owns all the cells involved. This is a real limitation, not a phase-one simplification.

Table 19. LTM element by element. Every row removes a different item from the interruption budget of the companion 22 Handover Overview §11 -- which is why LTM is a step change rather than an optimisation.

🔄
Release delta

LTM is fundamentally lower-latency than anything in Rel-15 or Rel-16 for one structural reason: it is the first NR mobility mechanism in which no RRC message is on the critical path. CHO removes the delivery of the RRC message from the critical path but still has the UE apply one. DAPS removes the gap but still runs the whole RRC procedure. LTM replaces the procedure with a MAC CE, and a MAC CE costs slots where an RRC transaction costs tens of milliseconds. Everything else about LTM follows from wanting that to be safe.

🔍
What you see in logs

The diagnostic consequence is worth internalising before you meet it: an LTM cell switch produces no XnAP activity, no F1AP UE context setup and no RRC reconfiguration. In a trace it is a UE whose serving cell changes with nothing in the control-plane log except a MAC CE and a change of scheduling cell. If a Rel-18 log appears to show cell changes with no signalling, that is not a broken capture -- it is LTM working. The companion 23 Xn Handover §18 flags the same point from the Xn side.

LTM's costs mirror its benefits. The candidate configurations have to be kept fresh, which means periodic RRC maintenance that a baseline handover does not need. The L1 measurement and reporting on candidate cells runs continuously, which costs uplink capacity and UE power. And the intra-CU restriction means LTM is a tool for dense intra-site mobility and beam-like cell switching, not a replacement for the inter-gNB handovers that most mobility events actually are.

18. Baseline, CHO, DAPS and LTM Side by Side

Figure 9. Interruption only -- the one axis on which all four are comparable. It is also the axis on which CHO looks weakest and is most valuable, which is why the table below has six more columns.
Baseline HOCHODAPSLTM
ReleaseRel-15Rel-16Rel-16Rel-18
Interruption, best case26 ms17.5 ms~1 ms on DAPS DRBs; 26 ms on the others~3 ms
Interruption, worst case without a failure68 ms32 ms~4 ms on DAPS DRBs~10 ms
Signalling cost per handoverOne Xn preparation, one RRC command, one CompleteN Xn preparations, one RRC command carrying N stored configurations, one Complete, one HANDOVER SUCCESS, N-1 cancellationsOne Xn preparation, one RRC command, one Complete, plus EARLY STATUS TRANSFER and the daps-SourceRelease reconfigurationOne RRC reconfiguration to load candidates -- amortised over many switches -- then one MAC CE per switch
Resource cost at candidatesOne prepared target, for ~25 msN prepared targets, for the life of the configuration -- C-RNTI, CFRA preamble and admitted GBR capacity at each (§5.1, §20.3)One prepared target, but held longer because the source is not released until the target says soN pre-configured candidates, but held by one gNB -- no cross-node reservation, which is why it is cheap
UE complexityBaselineStore up to 8 configurations and evaluate their conditions continuously. Modest.Two MAC entities, two RLC instances, two key sets, dual RF. The highest of the four.Continuous L1 measurement on candidates, pre-applied configurations, fast TCI switching. Moderate but pervasive.
Robustness benefitNone -- this is the baselineLarge. Removes the dominant too-late failure cause: the command not arriving.Small. The UE can fall back to a source link that is still up, but the command still has to arrive.Moderate. L1 reporting is fresher, so decisions are better -- but the MAC CE still has to arrive.
Where the decision is madeNetwork, before the commandUE, at execution, on its own live measurementsNetwork, before the commandNetwork, on L1 reports that are milliseconds old
Combinable with the others--Not with DAPS (§1). Combines with RACH-less execution.Not with CHO (§1). Restricted with carrier aggregation.Independent of both -- different scope (intra-CU)
Best used forEverything, still the overwhelming majority of handoversHigh-speed and marginal-coverage relations where too-late failures are measuredLatency-critical bearers on a homogeneous carrier, on devices that support itDense intra-site mobility and cell switching within one gNB

Table 20. The four mechanisms across every axis that matters. Read the robustness row against the interruption rows: no single number ranks these, which is why deployments enable different ones on different neighbour relations.

💡
Key point

The two rows that decide real deployments are resource cost at candidates and UE complexity, not the interruption rows. CHO is cheap in the device and expensive in the network; DAPS is the reverse; LTM is cheap in both but only works inside one gNB. That is a coherent story: each mechanism spends the resource its designers had available, and none of them is a free upgrade.

19. Failure Modes Across All Three Mechanisms

What failsWho detects itWhat the UE doesWhat it points at diagnostically
CHO: condition never firesNobody, until RLF. There is no timer on the wait (§6).Rides the source cell down to radio link failure, then re-establishes -- possibly into a stored candidate if attemptCondReconfig is seta3-Offset in CondTriggerConfig too large, or an accompanying A5 threshold that never clears. Look for RLF reports whose VarRLF-Report shows a strong neighbour that was a prepared candidate. This is a too-late failure with prepared candidates sitting unused, which is the worst possible outcome.
CHO: condition fires immediately on configurationThe source, as an unexpectedly fast executionExecutes within a measurement period of receiving the configurationThe CHO offset has been set equal to the reporting offset (§4). The UE is doing a slow baseline handover and paying for N prepared candidates. Symptom: near-zero time between RRCReconfigurationComplete on the source and PRACH at a candidate.
CHO: execution into a released contextThe candidate DU: PRACH on a reserved CFRA index with no matching UE contextT304 expires, then re-establishmentSource and candidate disagree about whether the candidate is still prepared: a missing condReconfigToRemoveList, a missing CONDITIONAL HANDOVER CANCEL, or a candidate supervision timer that is too short for CHO (§7, §9).
CHO: stale candidates accumulateNeighbour gNBs, as context and CFRA pressure -- never the sourceNothing; the UE is fineA source that does not cancel. Diagnose by counting prepared candidates against executions plus cancellations plus timer expiries, per gNB pair (§7).
CHO: ping-pong between two candidatesMRO, as repeated short staysExecutes, arrives, and the new cell's own CHO fires backA3-only conditions with no absolute floor. Add a CondEvent A5 to the condExecutionCond so both conditions must hold (§3).
CHO: forwarding gap after a successful executionThe target: it is scheduling the UE and has nothing to sendNothing -- the handover succeededThe HANDOVER SUCCESS round trip (§8). Excessive here means Xn latency or a slow source. Distinguish from an Xn-U problem by checking whether forwarded data eventually arrives.
DAPS: target releases the source too earlyThe UE's PDCP, as a reordering stall; the application, as a gapWaits t-Reordering for source-leg SDUs that will never come, then delivers with a holeTarget sent daps-SourceRelease before SN STATUS TRANSFER and the forwarded backlog completed (§15). Produces a worse gap than baseline, on a handover the KPIs call successful.
DAPS: wrong key applied to a legThe application, as corrupt data. Not RRC, not MAC, not PDCP.Delivers in-order, correctly numbered garbage upwardThe key must be selected by the delivering RLC entity, not by the bearer (§14.3). Signature: TCP checksum failures confined to the overlap window, with a clean RRC trace. If integrity protection is on for that DRB you get MAC-I failures instead, which is much easier to find.
DAPS: source never releasedThe source, as a context whose downlink activity outlives its uplinkNothing -- its PDCP discards the duplicatesLost HANDOVER SUCCESS, or broken release logic at the target (§13.2). Costs source PRBs and leaks source contexts.
DAPS: uplink power starvation at the overlapBoth cells, as uplink coverage loss on one or the otherSplits its power per DAPS-UplinkPowerConfig and may fail to close either linkp-DAPS-Source / p-DAPS-Target set without regard to the actual geometry (§16). At cell edge neither leg gets enough. Symptom: DAPS handovers that fail only at low RSRP, where baseline handovers succeeded.
DAPS: enabled on the wrong DRBNobody. Every counter is green.Nothing -- it works perfectly on the bearer that did not need itThe per-bearer decision of §11. Diagnose by decoding radioBearerConfig and comparing which DRB carries daps-Config against which 5QI the user actually notices.
DAPS: UE does not support itThe source, at capability evaluation -- before any handoverOrdinary baseline handoverNot a fault, but worth counting: the DAPS-eligible fraction of handovers bounds the feature's achievable benefit. Companion 26 UE Capability.
LTM: candidate configuration staleThe UE, on applying a switch command for a candidate whose configuration no longer matches the cellFails the switch and falls back to RRC-based recoveryCandidate maintenance not keeping pace with cell reconfiguration (§17). Rare, and hard to see because there is no RRC transaction to inspect.
LTM: TA no longer valid for a RACH-less switchThe target cell, as an uplink transmission outside its cyclic prefixThe switch's first uplink transmission is not received; recovery depends on implementationEarly TA acquired too long before the switch, or the UE moved. This is the same hazard RACH-less handover has always had (companion 04 Timing Advance).

Table 21. Fourteen failure modes. Four of them -- stale candidates, wrong-leg keys, early source release, and DAPS on the wrong bearer -- are invisible to every standard mobility KPI, because in all four cases the handover succeeded.

20. Worked Arithmetic

20.1 Interruption: baseline against CHO against DAPS

💡
INTERRUPTION, THREE WAYS

FR1, 30 kHz SCS. Target already in the measurement object. PRACH occasions every 10 ms. CFRA allocated. Step letters are those of the companion 22 Handover Overview §11.

Baseline handover

a decode and apply the RRCReconfiguration ... 10.0 ms

b release the source, retune ................ 1.0 ms

c fine sync on the target SSB ............... 3.0 ms

d wait for the next PRACH occasion (mean) ... 5.0 ms

e preamble transmission ..................... 0.5 ms

f RAR window until decoded .................. 3.0 ms

g TA applied, Complete transmitted .......... 2.0 ms

h first forwarded DL PDSCH at the target .... 1.5 ms

------------------------------------------------------

Total user-plane interruption ............. 26.0 ms

CHO -- step a collapses because the configuration was delivered and parsed while the source link was good; step c shrinks because the candidate has been measured continuously to evaluate its condition; step h grows because forwarding cannot start until HANDOVER SUCCESS reaches the source (§8).

a' activate an already-parsed condRRCReconfig . 1.0 ms (was 10.0)

b release the source, retune ................ 1.0 ms

c' fine sync -- candidate already tracked .... 1.0 ms (was 3.0)

d wait for the next PRACH occasion (mean) ... 5.0 ms

e preamble transmission ..................... 0.5 ms

f RAR window until decoded .................. 3.0 ms

g TA applied, Complete transmitted .......... 2.0 ms

------------------------------------------------------

UE off the air, a' to g ................... 13.5 ms

h' first forwarded DL PDSCH -- late forwarding 4.0 ms (was 1.5)

------------------------------------------------------

Total user-plane interruption ............. 17.5 ms

DAPS, for a DRB carrying daps-Config -- the source serves the UE through the whole of a to g, so none of it counts.

a..g source link carries data throughout ..... 0.0 ms

uplink switch at random-access completion .... 1.0 ms

downlink: both legs deliver into one PDCP .... 0.0 ms

------------------------------------------------------

Total, DAPS-configured DRB ................ 1.0 ms

Total, a DRB without daps-Config ........ 26.0 ms

The mixed case, which is the real one. A UE with DRB 1 (daps-Config set) and DRB 2 (not set), carrying equal traffic:

mean over the two bearers = (1.0 + 26.0) / 2 = 13.5 ms

-- indistinguishable from CHO on a per-UE average, while the experience is completely different: one bearer sees nothing and the other sees the full gap. Averaging interruption across bearers destroys the only information DAPS produces.

20.2 A CondEvent A3 evaluation, with real values

💡
CondEvent A3 EVALUATION

The scenario of the RSRP figure in §4, evaluated at t = 1300 ms. All quantities are SS-RSRP in dBm; all offsets are 0 dB unless stated.

Serving cell PCI 231 ..... Mp = -104 Ofp = 0 Ocp = 0

Candidate C PCI 419 ..... Mn = -88 Ofn = 0 Ocn = 0

Candidate B PCI 417 ..... Mn = -95 Ofn = 0 Ocn = 0

Reporting event A3: a3-Offset = 3 dB, hysteresis = 2 dB, TTT 160 ms.

entry: Mn + Ofn + Ocn - Hys > Mp + Ofp + Ocp + Off

i.e. Mn > Mp + Off + Hys = -104 + 3 + 2 = -99 dBm

Both candidates passed this at t = 880 ms, when the serving cell was

-97 and the threshold was -92: PCI 419 at -92 and PCI 417 at -93 --

which is why one report prepared both.

CondEvent A3: a3-Offset = 8 dB, hysteresis = 2 dB, TTT 80 ms.

execution threshold = Mp + Off + Hys = -104 + 8 + 2 = -94 dBm

candidate C (PCI 419): -88 > -94 -> TRUE, margin +6 dB

candidate B (PCI 417): -95 > -94 -> FALSE, short by 1 dB

So exactly one candidate qualifies. The condition holds for the 80 ms timeToTrigger, and at t = 1380 ms the UE applies condReconfigId 2 and accesses PCI 419.

Reading the result. Candidate B was the cell the network would have chosen at t = 880 ms -- it was the stronger of the two when the report was sent. By execution time it is 7 dB worse. A baseline handover committed at t = 880 ms would have moved the UE to the wrong cell; CHO moved it to the right one using a measurement 80 ms old instead of 500 ms old. That is the whole feature, in two subtractions.

Note also that B qualifies 320 ms later, at t = 1700 ms, as the serving cell keeps falling. An A3-only condition is eventually satisfied by every audible neighbour -- which is the argument for pairing it with a CondEvent A5 (§3).

20.3 The resource cost of preparing N candidates

💡
COST OF N CANDIDATES

A dense urban macro cell. Assumptions, all approximate and typical rather than specified:

connected UEs per cell ................. 300

neighbour relations per cell ............ 6

CHO candidates configured per UE ....... N = 4

CFRA preambles reserved per cell ....... 12 of the 64 per RACH occasion

fraction of UEs in an overlap region ... 40 %, so 120 UEs hold CHO

candidate configurations at any moment

Prepared contexts arriving at one cell. Each of the 6 neighbours has 120 CHO-configured UEs with 4 candidates each, and on average 4/6 of those candidates point at this cell:

6 neighbours x 120 UEs x (4 / 6) = 480 prepared contexts

against 300 UEs the cell is actually serving. Context occupancy is 2.6x the served population, and 3 of every 4 prepared contexts will never carry a packet.

CFRA preambles. If every prepared candidate needs one reserved preamble index:

480 required vs 12 reserved -> short by a factor of 40

This is not survivable, and it is why implementations do one of three things: allocate CFRA to only the highest-probability candidates; share preamble indices across UEs associated with different SSBs; or give CHO candidates contention-based access instead.

The consequence for §20.1. If a CHO candidate ends up on CBRA rather than CFRA, steps d to f grow by the contention resolution and the possibility of a collision -- commonly 10 to 20 ms. CHO's 17.5 ms becomes 27 to 37 ms, i.e. worse than baseline, while still delivering the robustness benefit. That trade is usually still worth making, but it has to be made knowingly.

Scaling. Everything above is linear in N. Going from N = 4 to N = 2 halves the prepared contexts and the preamble pressure and loses very little: the second candidate is chosen perhaps 15 to 25 % of the time, the third and fourth almost never. maxNrofCondCells is 8; the useful number is 2 or 3.

21. Illustrative Message Traces

🔍
ABOUT THESE TRACES

Illustrative trace. Field names and encodings follow 3GPP; the values are constructed for this document and are not a capture from any deployed or lab network. IP addresses are taken from the RFC 5737 documentation ranges and the PLMN is the reserved test PLMN 001-01, so nothing here can be mistaken for operator data.

One UE throughout, and the same identities as the companion 23 Xn Handover so the two documents can be read together. Source cell NR-CGI 001-01-0x0A1B2C001 (PCI 231), source C-RNTI 0x4C21. Candidate B is NR-CGI 001-01-0x0A1B3D002 (PCI 417) at 192.0.2.21, C-RNTI 0x5A03. Candidate C is NR-CGI 001-01-0x0A1B3D004 (PCI 419) at 203.0.113.31, C-RNTI 0x6B14. The source gNB is 192.0.2.11 and the UPF is 198.51.100.5. Two PDU sessions: 5 (5QI 9, DRB 1) and 6 (5QI 1, DRB 2).

21.1 RRCReconfiguration carrying conditionalReconfiguration

[RRC] RRCReconfiguration with conditionalReconfiguration, two candidates
10:14:22.104  [RRC-DL] SRB1  DL-DCCH-Message  RRCReconfiguration  702 bytes
              -- source keys; the UE is on PCI 231 and stays there
  rrc-TransactionIdentifier ........ 2
  criticalExtensions rrcReconfiguration
    measConfig
      measObjectToAddModList  { measObjectId 1: ssbFrequency 632640 }
      reportConfigToAddModList
        [0] reportConfigId 2   reportConfigNR eventTriggered
            eventA3  a3-Offset rsrp: 3   hysteresis 4 (= 2.0 dB)
                     timeToTrigger ms160   reportOnLeave FALSE
                     -- ordinary reporting: this is what prepared the two
        [1] reportConfigId 5   reportConfigNR condTriggerConfig
            condEventA3  a3-Offset rsrp: 8   hysteresis 4 (= 2.0 dB)
                         timeToTrigger ms80
                     -- no reportQuantity, no reportAmount: there is no report
      measIdToAddModList
        { measId 2, measObjectId 1, reportConfigId 2 }   -- reporting
        { measId 7, measObjectId 1, reportConfigId 5 }   -- CHO condition
    nonCriticalExtension
      conditionalReconfiguration-r16
        attemptCondReconfig-r16 ..... true
        condReconfigToAddModList-r16
          [0] condReconfigId-r16 ......... 1
              condExecutionCond-r16 ...... { 7 }        -- measId 7
              condRRCReconfig-r16  (OCTET STRING, 274 bytes)
                RRCReconfiguration                      -- authored by PCI 417
                  radioBearerConfig  drb-ToAddModList { 1 reestablishPDCP,
                                                        2 reestablishPDCP }
                    securityConfig  cipheringAlgorithm nea2  keyToUse master
                  masterCellGroup -> CellGroupConfig
                    spCellConfig  reconfigurationWithSync
                      spCellConfigCommon  physCellId 417
                                          absoluteFrequencySSB 632640
                      newUE-Identity ..... 0x5A03
                      t304 ............... ms100
                      rach-ConfigDedicated uplink cfra
                        ssb-ResourceList { ssb-Index 3, ra-PreambleIndex 61 }
                    masterKeyUpdate  keySetChangeIndicator FALSE
                                     nextHopChainingCount 5
          [1] condReconfigId-r16 ......... 2
              condExecutionCond-r16 ...... { 7 }        -- same condition
              condRRCReconfig-r16  (OCTET STRING, 268 bytes)
                RRCReconfiguration                      -- authored by PCI 419
                  masterCellGroup -> CellGroupConfig
                    spCellConfig  reconfigurationWithSync
                      spCellConfigCommon  physCellId 419
                      newUE-Identity ..... 0x6B14
                      t304 ............... ms150       -- different vendor policy
                      rach-ConfigDedicated uplink cfra
                        ssb-ResourceList { ssb-Index 1, ra-PreambleIndex 57 }
                    masterKeyUpdate  nextHopChainingCount 5    -- same NCC

10:14:22.116  [RRC-UL] SRB1  RRCReconfigurationComplete  transactionId 2
10:14:22.116  [RRC]    2 conditional reconfigurations stored
10:14:22.116  [RRC]    NO T304 started; source cell retained; C-RNTI 0x4C21 kept
10:14:22.116  [MEAS]   measId 7 now evaluated against condReconfigId 1 and 2

Listing 4. Two candidates, one shared condExecutionCond, two different t304 values -- because the two stored configurations were authored by two different gNBs. Note the identical nextHopChainingCount: one NCC, two different K_NG-RAN* values derived from two different PCIs (§5.1).

21.2 The UE executes one candidate

[UE] CHO evaluation and execution of condReconfigId 2
-- UE-side view. Nothing in this block appears in the source gNB's log.

10:14:22.916  [MEAS] measId 7  L3-filtered SS-RSRP:
                     serving PCI 231 = -104   PCI 419 = -90   PCI 417 = -94
10:14:22.916  [MEAS] condEventA3 threshold = Mp + a3-Offset + Hys
                                          = -104 + 8 + 2 = -94 dBm
10:14:22.916  [MEAS] condReconfigId 2 (PCI 419): -90 > -94  -> entry TRUE
10:14:22.916  [MEAS] condReconfigId 1 (PCI 417): -94 > -94  -> entry FALSE
10:14:22.916  [MEAS] timeToTrigger ms80 started for condReconfigId 2

10:14:22.996  [MEAS] condition held 80 ms -> CHO EXECUTION, condReconfigId 2
10:14:22.996  [RRC]  applying stored condRRCReconfig (268 bytes, pre-parsed)
10:14:22.996  [RRC]  T304 started (ms150)      -- candidate 2's own value
10:14:22.996  [RRC]  condReconfigId 1 retained in case of re-establishment
                     (attemptCondReconfig = true)
10:14:22.997  [MAC]  source cell released, MAC reset, C-RNTI 0x4C21 discarded
10:14:22.998  [PHY]  retune to PCI 419, absoluteFrequencySSB 632640
10:14:22.999  [PHY]  SSB index 1 acquired (already tracked for measId 7)

10:14:23.004  [MAC]  PRACH: ra-PreambleIndex 57, SSB 1   -- CFRA, no contention
10:14:23.007  [MAC]  RAR received: TA command 19, UL grant 8 PRB
10:14:23.009  [RRC]  RRCReconfigurationComplete -> C-RNTI 0x6B14, LCID 1
10:14:23.009  [RRC]  T304 stopped
10:14:23.009  [RRC]  ALL conditional reconfigurations released (ids 1 and 2)
10:14:23.013  [PDCP] DL DRB 1: first PDSCH  -- 4 ms after Complete, no data yet

-- Elapsed, source release to Complete: 13 ms. Elapsed to first DL data: 17 ms.
-- Compare the 26 ms of a baseline handover (20.1). The 4 ms tail is the
-- late-forwarding cost of 20.1's step h'.

Listing 5. Execution end to end, in 13 ms of air time, with no signalling from the source. The last line of the RRC block is the Rel-16 behaviour that prevents chaining: all candidates are released, including the unused one, the moment the handover completes.

21.3 XnAP: EARLY STATUS TRANSFER, HANDOVER SUCCESS and cancellation

[XnAP] EARLY STATUS TRANSFER, HANDOVER SUCCESS, CONDITIONAL HANDOVER CANCEL
-- Source gNB view. Note the 800 ms gap in the middle: the source had
-- nothing to do and nothing to log while the UE evaluated.

10:14:22.120  [XnAP-TX] peer 0x0A1B3D (192.0.2.21)  EARLY STATUS TRANSFER
  initiatingMessage  procedureCode = 15 (earlyStatusTransfer)  criticality = ignore
  sourceNG-RANnodeUEXnAPID ......... 0x00007C41
  targetNG-RANnodeUEXnAPID ......... 0x0000B120
  procedureStage
    firstDLCOUNT
      drbsSubjectToEarlyStatusTransfer-List
        [0] drbID 1   firstDLCOUNT  pdcp-SN = 8014   hfn = 7
        -- no entry for drbID 2: RLC-UM voice, no numbering to preserve
  -- sent to BOTH candidates; the source is still assigning DL SNs itself
10:14:22.121  [XnAP-TX] peer 0x0A1B3F (203.0.113.31)  EARLY STATUS TRANSFER
                        drbID 1  firstDLCOUNT  pdcp-SN = 8014  hfn = 7

              ... 875 ms with no XnAP activity for this UE ...
              ... uplink from C-RNTI 0x4C21 simply stops at 10:14:22.997 ...

10:14:23.041  [XnAP-RX] peer 0x0A1B3F (203.0.113.31)  HANDOVER SUCCESS
  initiatingMessage  procedureCode = 16 (handoverSuccess)  criticality = ignore
  sourceNG-RANnodeUEXnAPID ......... 0x00007C41
  targetNG-RANnodeUEXnAPID ......... 0x0000C7A2
  -- FIRST notification that the UE went to PCI 419, 44 ms after it left
10:14:23.041  [RRC]     source DL transmission on DRB 1 stopped, SNs frozen

10:14:23.042  [XnAP-TX] peer 0x0A1B3F  SN STATUS TRANSFER
  drbsSubjectToStatusTransfer-List
    [0] drbID 1  ul-COUNTValue pdcp-SN = 3277  hfn = 2
                 dl-COUNTValue pdcp-SN = 8061  hfn = 7
                 -- 47 SNs assigned since the EARLY STATUS TRANSFER above
10:14:23.043  [GTP-U-TX] Xn-U 192.0.2.11 -> 203.0.113.31  TEID 0x00C10001
                        38 G-PDUs, ext hdr PDCP PDU Number, SNs 8023..8060
10:14:23.044  [PDCP-SRC] 9 SDUs discarded (discardTimer ms100 expired)
                        -- the price of the 44 ms notification delay

10:14:23.045  [XnAP-TX] peer 0x0A1B3D (192.0.2.21)
                        CONDITIONAL HANDOVER CANCEL
  sourceNG-RANnodeUEXnAPID ......... 0x00007C41
  targetNG-RANnodeUEXnAPID ......... 0x0000B120
  cause  radioNetwork ............... normal-release
  -- candidate B held C-RNTI 0x5A03 and CFRA index 61 for 941 ms
10:14:23.081  [XnAP-RX] peer 0x0A1B3F  UE CONTEXT RELEASE
                        -- after the target's NGAP path switch

Listing 6. The 44 ms between the UE leaving and HANDOVER SUCCESS arriving is CHO's real cost: nine downlink SDUs hit discardTimer and were never forwarded. EARLY STATUS TRANSFER went to both candidates at configuration time, which is how the chosen one could start numbering immediately (§8.1).

21.4 RRCReconfiguration with daps-Config on one DRB

[RRC] RRCReconfiguration with daps-Config on DRB 1 only
-- A different handover, same UE identities. Baseline Xn preparation
-- (companion 23), with one flag added by the target's RRC.

11:07:45.220  [RRC-DL] SRB1  DL-DCCH-Message  RRCReconfiguration  318 bytes
  rrc-TransactionIdentifier ........ 0
  criticalExtensions rrcReconfiguration
    radioBearerConfig
      drb-ToAddModList
        [0] drb-Identity ............. 1
            reestablishPDCP ......... (absent)   -- NOT re-established: DAPS
            pdcp-Config  t-Reordering ms100  discardTimer ms100
                         pdcp-SN-SizeDL len18bits  pdcp-SN-SizeUL len18bits
            daps-Config-r16 ......... true       -- THE flag
        [1] drb-Identity ............. 2
            reestablishPDCP ......... true       -- ordinary bearer
            daps-Config-r16 ......... (absent)
                     -- DRB 2 is 5QI 1 voice and takes the full 26 ms gap.
                     -- See the trap callout in section 11.
      securityConfig
        securityAlgorithmConfig  cipheringAlgorithm nea2
                                 integrityProtAlgorithm nia2
        keyToUse ................... master
    masterCellGroup  (OCTET STRING -> CellGroupConfig, 204 bytes)
      spCellConfig
        reconfigurationWithSync
          spCellConfigCommon  physCellId 419  absoluteFrequencySSB 632640
          newUE-Identity ......... 0x6B14
          t304 ................... ms150
          rach-ConfigDedicated uplink cfra
            ssb-ResourceList { ssb-Index 1, ra-PreambleIndex 57 }
          daps-UplinkPowerConfig-r16
            p-DAPS-Source-r16 .......... 20      -- dBm
            p-DAPS-Target-r16 .......... 20      -- dBm
            uplinkPowerSharingDAPS-Mode-r16 .. semi-static-mode1
    masterKeyUpdate  keySetChangeIndicator FALSE  nextHopChainingCount 6

11:07:45.231  [RRC]  applying reconfiguration
11:07:45.231  [MAC]  source MAC entity RETAINED, C-RNTI 0x4C21 still valid
11:07:45.231  [MAC]  second MAC entity created for PCI 419, C-RNTI 0x6B14
11:07:45.231  [PDCP] DRB 1 -> DAPS bearer: 2 RLC legs, 2 key sets,
                     1 SN space, t-Reordering ms100 unchanged
11:07:45.231  [PDCP] DRB 2 -> PDCP re-established, source leg torn down
11:07:45.231  [RRC]  T304 started (ms150)
11:07:45.232  [PDCP] DL DRB 1 continues on the source -- no gap

Listing 7. The two DRBs diverge on one line. DRB 1 keeps its PDCP state and gains a second leg; DRB 2 re-establishes PDCP and loses its source leg immediately, which is the ordinary handover behaviour and the ordinary 26 ms gap. p-DAPS-Source and p-DAPS-Target at 20 dBm each is a 3 dB cut on both legs against a 23 dBm power class.

21.5 The overlap, and the source release

[MAC / PDCP / RRC] the DAPS overlap and daps-SourceRelease
-- Both cells' schedulers, interleaved, for one UE.

11:07:45.232  [SRC-MAC] PDSCH to C-RNTI 0x4C21, DRB 1, 12 PRB   -- source
11:07:45.234  [SRC-MAC] UL-SCH from C-RNTI 0x4C21, DRB 1        -- source UL
11:07:45.236  [TGT-PHY] PRACH detected: preamble 57, SSB 1, TA est 19
11:07:45.236  [SRC-MAC] PDSCH to C-RNTI 0x4C21, DRB 1, 12 PRB   -- still source
11:07:45.238  [TGT-MAC] RAR sent: TA command 19, UL grant 8 PRB
11:07:45.241  [TGT-MAC] UL-SCH from C-RNTI 0x6B14, LCID 1, 28 bytes
11:07:45.241  [RRC]     RRCReconfigurationComplete, MAC-I verified (new K_RRCint)
11:07:45.241  [UE-PDCP] *** UPLINK SWITCH for DRB 1: source leg -> target leg
11:07:45.241  [UE-PDCP] retransmitting 4 PDCP SDUs (SN 3301..3304) on the
                        target leg -- submitted to source RLC, not confirmed
11:07:45.241  [RRC]     T304 stopped

-- OVERLAP: both cells transmitting downlink DRB 1 into ONE PDCP entity
11:07:45.243  [SRC-MAC] PDSCH to C-RNTI 0x4C21, DRB 1, SNs 8210..8213
11:07:45.244  [XnAP-RX] HANDOVER SUCCESS from 203.0.113.31
11:07:45.245  [XnAP-TX] SN STATUS TRANSFER  drbID 1  dl-COUNT SN 8214 hfn 7
11:07:45.245  [SRC-PDCP] DL SN assignment stopped; 21 SDUs forwarded on Xn-U
11:07:45.248  [TGT-MAC] PDSCH to C-RNTI 0x6B14, DRB 1, SNs 8214..8217
11:07:45.249  [UE-PDCP] DRB 1 rx window: 8210-8213 via SOURCE leg (source key),
                        8214-8217 via TARGET leg (target key), delivered in order
11:07:45.252  [SRC-MAC] PDSCH to C-RNTI 0x4C21, DRB 1, SN 8209 (RLC retx)
                        -- a straggler; within t-Reordering, so not lost

11:07:45.258  [GTP-U-RX] End Marker on the old N3 tunnel, forwarded on Xn-U
11:07:45.261  [TGT-RRC] forwarding complete; overlap may end
11:07:45.262  [RRC-DL] SRB1 (TARGET)  RRCReconfiguration  22 bytes
  rrc-TransactionIdentifier ........ 1
  criticalExtensions rrcReconfiguration
    nonCriticalExtension
      daps-SourceRelease-r16 ........ true
  -- nothing else. This message exists only to end the overlap.

11:07:45.268  [UE-MAC]  source MAC entity released, HARQ flushed,
                        C-RNTI 0x4C21 discarded
11:07:45.268  [UE-RLC]  source RLC entities released
11:07:45.268  [UE-PDCP] DRB 1: source key set and ROHC context #1 released;
                        DAPS bearer -> ordinary bearer; SN space UNCHANGED
11:07:45.269  [RRC-UL] SRB1 (TARGET)  RRCReconfigurationComplete  transactionId 1
11:07:45.274  [XnAP-RX] UE CONTEXT RELEASE from 203.0.113.31

-- DRB 1 downlink interruption: 0 ms. Uplink interruption: 1 slot at the
-- switch. Overlap duration: 37 ms. DRB 2 interruption: 26 ms, unchanged.

Listing 8. Two C-RNTIs live at once, two keys deciphering one bearer, and a 22-byte RRCReconfiguration from the target to end it. The straggler at 11:07:45.252 is the case §14.1 is about -- a t-Reordering shorter than the overlap would have discarded it and produced the gap DAPS exists to remove.

21.6 A failure path: CHO execution fails, second candidate used

[UE] CHO execution failure and recovery via a second stored candidate
-- Same UE, a later handover. Candidate C's radio collapsed between the
-- condition firing and the preamble being transmitted (a lift shaft).

11:52:08.410  [MEAS] condReconfigId 2 (PCI 419) condition met, TTT elapsed
11:52:08.410  [RRC]  CHO execution, condReconfigId 2; T304 started (ms150)
11:52:08.411  [MAC]  source released, C-RNTI 0x4C21 discarded
11:52:08.418  [MAC]  PRACH: ra-PreambleIndex 57, SSB 1   -- attempt 1
11:52:08.428  [MAC]  ra-ResponseWindow expired, no RAR   -- attempt 1 failed
11:52:08.436  [MAC]  PRACH: preamble 57, power ramped +2 dB   -- attempt 2
11:52:08.446  [MAC]  ra-ResponseWindow expired, no RAR   -- attempt 2 failed
11:52:08.454  [MAC]  PRACH: preamble 57, power ramped +2 dB   -- attempt 3
11:52:08.464  [MAC]  ra-ResponseWindow expired, no RAR
11:52:08.560  [RRC]  *** T304 EXPIRY (ms150) on condReconfigId 2 ***
11:52:08.560  [RRC]  handover failure; VarRLF-Report stored
                     (failedPCellId 419, reestablishmentCellId pending,
                      timeConnFailure 150, connectionFailureType hof)
11:52:08.560  [RRC]  reverting to the source configuration -- source is gone
11:52:08.560  [RRC]  initiating RRC re-establishment

11:52:08.561  [RRC]  attemptCondReconfig = true: checking stored candidates
11:52:08.562  [PHY]  cell selection: PCI 417, SS-RSRP -95   -- best available
11:52:08.562  [RRC]  PCI 417 IS the target of stored condReconfigId 1
11:52:08.562  [RRC]  applying condReconfigId 1 instead of
                     RRCReestablishmentRequest    -- the CHO shortcut
11:52:08.562  [RRC]  T304 started (ms100)         -- candidate 1's own value
11:52:08.569  [MAC]  PRACH: ra-PreambleIndex 61, SSB 3   -- CFRA at PCI 417
11:52:08.572  [MAC]  RAR received: TA command 24, UL grant 8 PRB
11:52:08.574  [RRC]  RRCReconfigurationComplete -> C-RNTI 0x5A03
                     ueMeasurementsAvailable: rlf-InfoAvailable true
11:52:08.574  [RRC]  T304 stopped; all conditional reconfigurations released

-- Total outage: 08.411 to 08.574 = 163 ms, of which 150 ms was T304 at a
-- cell that was never going to answer. No RRCReestablishmentRequest was
-- ever sent: no SRB0 exchange, no context fetch, no security re-derivation.
-- Without attemptCondReconfig this would have been 250-350 ms.
-- MRO will read this from the RLF report as a WRONG-CELL execution, and the
-- fix is a CondEvent A5 alongside the A3 so that a cell about to be shadowed
-- cannot qualify on relative strength alone.

Listing 9. The attemptCondReconfig shortcut earning its place. Note that T304 dominates the outage: a shorter t304 at candidate 2 would have cut the total almost in half, which is the argument for not setting t304 generously just because CHO makes failures rarer.

22. Release Deltas: Rel-15 to Rel-18

ReleaseWhat was addedWhy it matters when reading a trace
Rel-15Neither feature exists. Baseline handover only: one prepared target, break-before-make, reconfigurationWithSync, T304.The baseline of the companion 22 Handover Overview and 23 Xn Handover. A Rel-15 peer cannot participate in CHO or DAPS at all, so a mixed-release network has neighbour relations on which neither feature is available.
Rel-16: CHOconditionalReconfiguration with condReconfigToAddModList / condReconfigToRemoveList and attemptCondReconfig; condTriggerConfig with CondEvent A3 and A5; maxNrofCondCells = 8; XnAP Conditional Handover Information Request, CONDITIONAL HANDOVER CANCEL and HANDOVER SUCCESSBreaks the one-preparation-per-handover assumption. A source may hold several prepared targets simultaneously, and cancellation becomes routine rather than exceptional. Correlating a handover now needs the condReconfigId, not just the target cell.
Rel-16: DAPSdaps-Config per DRB; DAPS-UplinkPowerConfig in reconfigurationWithSync; daps-SourceRelease in RRCReconfiguration; the DAPS bearer in TS 38.323; XnAP EARLY STATUS TRANSFERTwo active C-RNTIs for one UE stop being a bug. The source keeps transmitting after the UE has arrived at the target, and the release arrives on the target's SRB1.
Rel-16: MRO for the new mechanismsXn Failure Indication and Handover Report extended so a CHO failure can be attributed; RLF report fields for the conditional caseA too-early / too-late / wrong-cell classification is now available for CHO executions, which is the only automated way to tune CondTriggerConfig at scale.
Rel-17CondEvent A4 for conditional triggers; conditional PSCell addition and change (CPAC) reusing the same machinery for NR-DC; the DL discarding stage of EARLY STATUS TRANSFER; RLF report additions naming the CHO candidate setcondTriggerConfig may now carry an absolute-threshold event, which is what makes conditional inter-frequency and PSCell mobility sensible. CPAC traces look like CHO traces and are not -- check whether the stored configuration is an SCG configuration.
Rel-18LTM (§17): pre-configured candidates, an LTM Cell Switch Command MAC CE, TCI-state-based switching, early TA acquisition and RACH-less execution, intra-CU scope. Also subsequent CHO, in which the conditional configuration survives an execution so a UE can chain one CHO into the next -- motivated largely by NTN, where the candidate set is predictable from ephemeris.Two things break older assumptions. LTM produces cell changes with no RRC and no XnAP at all. Subsequent CHO breaks the Rel-16 rule in §6 that execution discards every candidate -- so a Rel-18 UE may execute twice from one configuration, and a trace showing that is not a duplicate.

Table 22. Rel-16 is the release that changes how a mobility trace reads; Rel-18 is the release that changes what is in one at all. DAPS has been essentially unchanged since Rel-16, which is unusual and reflects how little of it is negotiable.

🔄
Release delta

Subsequent CHO is worth flagging because it invalidates a rule this document states plainly for Rel-16: that a successful execution releases all stored candidates (§6). With subsequent CHO the selected candidates can be retained across the execution, which is what makes chained conditional mobility possible without a round trip to configure the next hop. If you are reading a Rel-18 log and see a second CHO execution with no intervening conditionalReconfiguration, this is why.

23. Reading CHO and DAPS in Logs: A Checklist

  1. Establish which mechanism you are looking at, from the RRC message. conditionalReconfiguration present means CHO. daps-Config on any DRB-ToAddMod means DAPS. Neither means baseline. A cell change with no RRC message at all, on a Rel-18 network, means LTM (§17). Do not infer the mechanism from the Xn trace -- CHO and baseline preparations look almost identical there.
  2. Count the preparations. N HANDOVER REQUESTs for one UE within a few milliseconds is CHO preparing N candidates (§5). Confirm by looking for the Conditional Handover Information Request IE; a peer that does not implement it will hold the contexts for a baseline-length timer and release them early, which is the failure in the §5 trap.
  3. Compare the CondEvent offset against the reporting offset. They should not be equal (§4). If a3-Offset in condTriggerConfig matches a3-Offset in the reporting eventA3, expect executions within a measurement period of configuration -- measure the interval from RRCReconfigurationComplete on the source to PRACH at a candidate, and alarm if the median is under 100 ms.
  4. Do not look for a CHO execution in the source's log. There is none. The source sees uplink stop, then XnAP HANDOVER SUCCESS 30 to 60 ms later (§6). To time the execution you need the chosen candidate's PRACH timestamp, so the source and candidate logs have to be clock-aligned before any of this is measurable.
  5. Measure the HANDOVER SUCCESS delay and the SDUs it costs. From the candidate's RRCReconfigurationComplete to the source's receipt of HANDOVER SUCCESS is dead time in which the source cannot forward and discardTimer keeps running (§8, §21.3). Count discarded SDUs per CHO handover; a rising count is Xn latency, not radio.
  6. Reconcile prepared candidates against executions plus cancellations. Per gNB pair: prepared = executed + cancelled + timer-expired. A persistent shortfall closed only by timer expiries is a source that is not sending CONDITIONAL HANDOVER CANCEL, and the pain lands on its neighbours (§7).
  7. On a PRACH with a reserved CFRA index and no UE context, suspect a released candidate. In CHO this almost always means the source and the candidate disagree about whether the candidate was still prepared, not that the target gave up too early (§9). Check the candidate's supervision timer value first -- it must be much longer for CHO than for baseline.
  8. For DAPS, verify the source keeps transmitting after the UE arrives. That is the feature working, not a stuck context (§13.2). What you should not see is source downlink continuing long after XnAP UE CONTEXT RELEASE, or a source context whose last downlink is much later than its last uplink.
  9. Find daps-SourceRelease on the target's SRB1, not the source's. It is a tiny RRCReconfiguration with essentially nothing else in it (§15, §21.5). Its absence with a completed handover is the leak in the previous step. Its arrival before SN STATUS TRANSFER and the forwarded backlog is the early-release failure -- and that one produces a worse gap than baseline while every KPI stays green.
  10. For a DAPS bearer, check t-Reordering against the overlap duration. A source-leg straggler arriving after t-Reordering has expired is discarded, which reintroduces the gap DAPS removed (§14.1). Measure the overlap -- command to daps-SourceRelease -- and confirm t-Reordering comfortably exceeds the latency spread between the two legs.
  11. Check which DRB actually carries daps-Config. Compare it against the 5QI the user notices (§11). This costs one decode and is the single highest-yield check in the DAPS list, because getting it wrong is completely invisible to every counter.
  12. When a DAPS handover succeeds but the application sees corruption, go to the keys. A PDCP entity that selects the ciphering key by bearer rather than by delivering RLC entity produces in-order, correctly numbered garbage (§14.3). The signature is TCP checksum failures confined to the overlap window with a clean RRC and MAC trace -- and if integrity protection happens to be enabled on that DRB you get loud MAC-I failures instead, which is a much easier day.
  13. Classify every CHO failure with the RLF report, not with counters. connectionFailureType, failedPCellId and the candidate list in VarRLF-Report tell you whether the condition fired at the wrong cell, too early, or never (§19). Counters alone cannot separate "the condition never fired" from "there were no candidates", and those have opposite fixes.

24. Glossary

TermExpansionMeaning in this document
CHOConditional handoverRel-16. Up to 8 candidate targets prepared in advance, each with a stored complete RRCReconfiguration and an execution condition the UE evaluates itself.
DAPSDual Active Protocol StackRel-16. Per-DRB make-before-break: the source link keeps carrying data while the target link is established.
LTML1/L2-triggered mobilityRel-18. Pre-configured candidates switched by a MAC CE rather than an RRC reconfiguration, optionally RACH-less, intra-CU in Rel-18 (§17).
conditionalReconfiguration--The Rel-16 IE in RRCReconfiguration holding the whole CHO configuration: the add/mod list, the remove list and attemptCondReconfig.
condReconfigId--INTEGER (1..8). Identifies one stored candidate configuration, not a cell.
condExecutionCond--One or two measId values. Where there are two, both must be satisfied for execution.
condRRCReconfig--An OCTET STRING containing a complete stored RRCReconfiguration, authored by the candidate gNB, including its own reconfigurationWithSync and its own t304.
CondEvent A3 / A5 / A4--Measurement events whose consumer is CHO evaluation rather than a MeasurementReport. Identical inequalities to the reporting events of the same names; configured in condTriggerConfig (§4).
attemptCondReconfig--Tells the UE to apply a stored candidate during RRC re-establishment instead of sending RRCReestablishmentRequest (§9).
condReconfigToRemoveList--The list of condReconfigId values the UE should discard. The "release list" in informal usage (§7).
HANDOVER SUCCESS--XnAP class 2 message, Rel-16, target to source: the only way a source learns which CHO candidate the UE chose (§8).
CONDITIONAL HANDOVER CANCEL--XnAP class 2 message cancelling one prepared candidate. Routine in CHO, not exceptional (§7).
EARLY STATUS TRANSFER--XnAP class 2 message conveying the first downlink COUNT the target should use, sendable before the source stops assigning SNs (§8.1).
daps-Config--ENUMERATED {true} per DRB-ToAddMod. Makes that one DRB a DAPS bearer. There is no per-UE equivalent (§11).
DAPS bearer--A DRB whose PDCP entity has two RLC legs beneath it, with per-leg security and header compression but a single SN space and reordering window (§12, §14).
daps-SourceRelease--The flag in an RRCReconfiguration sent by the target that ends the dual-connection period (§15).
DAPS-UplinkPowerConfig--p-DAPS-Source, p-DAPS-Target and uplinkPowerSharingDAPS-Mode: how the UE splits its transmit power between two cells during the overlap (§11).
Overlap period--In DAPS, the interval from applying the reconfiguration to receiving daps-SourceRelease. Typically 30 to 60 ms.
Uplink switch--The instant at which PDCP stops submitting to the source RLC and starts submitting to the target RLC. A hard switch at random-access completion, not a period of duplication (§13).
Break-before-make / make-before-break--The baseline pattern, in which the source is released before the target is tried, against the DAPS pattern, in which it is not (§10).
maxNrofCondCells--8. The ceiling on stored candidates; 2 or 3 is the useful number (§20.3).

25. References

  • 3GPP TS 38.331 -- RRC protocol specification. Clause 5.3.5.13 (conditional reconfiguration: addition/modification, removal, evaluation and execution, and the re-establishment interaction), clause 5.3.5.5 (reconfiguration with sync and the DAPS behaviour), clause 5.5.4 (measurement event and CondEvent trigger conditions), and the IE definitions for ConditionalReconfiguration-r16, CondReconfigToAddMod-r16, CondTriggerConfig-r16, ReconfigurationWithSync, DAPS-UplinkPowerConfig-r16, DRB-ToAddMod and RadioBearerConfig.
  • 3GPP TS 38.300 -- NR overall description. Clause 9.2.3 (mobility in RRC_CONNECTED), clause 9.2.3.4 (conditional handover), clause 9.2.3.5 (DAPS handover, including the uplink switch and the source release), and the Rel-18 clauses on L1/L2-triggered mobility.
  • 3GPP TS 38.423 -- Xn Application Protocol (XnAP). Clause 8.2 (UE-associated procedures, including Conditional Handover Cancel, Handover Success and Early Status Transfer), clause 9.1.1 (message and IE definitions, including the Conditional Handover Information Request IE and DRBsSubjectToEarlyStatusTransfer-List), clause 9.2.6 (Cause).
  • 3GPP TS 38.323 -- PDCP specification. Clause 4.2 (functional model, including the DAPS bearer with its per-leg security and header compression), clause 5.2 (reordering and duplicate discard), and the uplink data-switching behaviour for DAPS bearers.
  • 3GPP TS 38.321 -- MAC protocol specification. The two-MAC-entity operation during DAPS, and the Rel-18 LTM Cell Switch Command MAC CE.
  • 3GPP TS 38.306 -- UE radio access capabilities. daps-HO and its intra-/inter-frequency, per-DRB and uplink-power-sharing sub-capabilities; the conditional-handover capability fields.
  • 3GPP TS 33.501 -- Security architecture and procedures for 5G. Clause 6.9.2 (key handling in handover, including the per-candidate K_NG-RAN* derivation and the two simultaneous key sets of a DAPS bearer), Annex A (the derivation function).
  • 3GPP TS 38.401 -- NG-RAN architecture description. Clause 8.2 and the CU/DU aspects of preparing a candidate, which apply once per candidate in CHO.
  • 3GPP TS 38.473 -- F1 Application Protocol (F1AP). UE Context Setup at each candidate DU, which is where a candidate's C-RNTI and CFRA preamble are actually allocated.
  • 3GPP TS 38.133 -- Requirements for support of radio resource management. The interruption-time and measurement-delay requirements the arithmetic in §20.1 is built on.
  • 3GPP TR 38.835 and the Rel-16 mobility enhancement study items -- background rationale for CHO and DAPS, including the interruption budgets that motivated each.

Companion documents in this set

  • 22 Handover Overview -- the framework both mechanisms modify: the handover taxonomy, the three phases, reconfigurationWithSync, T304, the 26 ms interruption budget that §20.1 starts from, and the MRO too-early / too-late / wrong-cell classification. Read it first.
  • 23 Xn Handover -- the procedure CHO runs N times and DAPS runs once: XnAP message by message, the transparent container principle that makes each candidate the author of its own stored condRRCReconfig, SN status transfer, and data forwarding.
  • 24 NG / N2 Handover -- the same, for the case where the source and target have no Xn. Both mechanisms are Xn-centric in practice, and the AMF-relayed variant is where their preparation costs bite hardest.
  • 20 Measurements and Events -- measConfig, measId, the A3 and A5 inequalities, layer-3 filtering and timeToTrigger. Everything in §4 is an application of that document.
  • 21 Measurement Gaps and SMTC -- how the UE measures the candidates it is evaluating, and why a candidate that is not in an active measurement object can never satisfy its condition.
  • 16 RLM and RLF -- where a T304 expiry goes next, and the VarRLF-Report fields that make a CHO failure diagnosable (§19, §21.6).
  • 15 RRC Procedures -- RRC re-establishment, and the exchange that attemptCondReconfig lets a UE skip entirely (§9).
  • 26 UE Capability -- daps-HO, its sub-capabilities, and the conditional-handover capability fields that gate both features per device.
  • 27 AS Security Mode -- K_NG-RAN*, the NCC, and the horizontal and vertical derivations behind the N per-candidate keys of §5.1 and the two simultaneous key sets of §14.3.
  • 03 Random Access -- the CFRA procedure every candidate reserves a preamble for, and the CBRA fallback that §20.3 ends up in.
  • 04 Timing Advance -- the TA validity question behind RACH-less execution and LTM's early TA acquisition (§17).
  • 07 MAC PDU and CEs -- the MAC CE framing that LTM's cell switch command uses instead of an RRC procedure.