>
Home5G NRMAC — Medium Access ControlBeam Failure Recovery
🧩 MAC — Medium Access ControlIntermediate

Beam Failure Recovery (MAC) in 5G NR

Detecting beam failure and recovering via a dedicated RACH procedure.

📚 3GPP-basedTS 38.321TS 38.213

At FR1 a cell is roughly a place. At FR2 it is a direction. Path loss at 28 GHz is high enough that neither end can afford an omnidirectional pattern, so both concentrate their energy into narrow beams and the link exists only while those two beams point at each other. That arrangement buys the link budget that makes mmWave work at all, and it introduces a failure mode that FR1 barely has: the beam pair can break while everything else — the cell, the security context, the bearers, the C-RNTI — remains completely valid.

Contents
  1. 01Why Beams Fail, and Why That Is Not a Cell Failure
  2. 02Beam Management in One Page: CORESETs, TCI States, Beam Pairs
  3. 03Three Nested Timescales: Beam, Cell, Connection
  4. 04Beam Failure Detection: Which Reference Signals
  5. 05RLM and BFD: the Same Signals, Different Thresholds
  6. 06The BFI Counter and beamFailureDetectionTimer
  7. 07Candidate Beam Identification
  8. 08The Recovery Request: Contention-Free RACH on the Chosen Beam
  9. 09The Response, and What the UE Assumes Afterwards
  10. 10When Recovery Itself Fails: the Route to RLF
  11. 11SCell Beam Failure Recovery (Rel-16): the BFR MAC CEs
  12. 12Rel-17: Per-TRP BFR and Multi-CORESET-Pool Operation
  13. 13Timers, Counters and Parameter Reference
  14. 14Failure Modes and What Each One Means
  15. 15Configuration Reference (ASN.1)
  16. 16Illustrative Message Traces
  17. 17Release Deltas: Rel-15 to Rel-18
  18. 18Reading BFR in Logs: A Checklist
  19. 19Glossary
  20. 20References

1. Why Beams Fail, and Why That Is Not a Cell Failure

At FR1 a cell is roughly a place. At FR2 it is a direction. Path loss at 28 GHz is high enough that neither end can afford an omnidirectional pattern, so both concentrate their energy into narrow beams and the link exists only while those two beams point at each other. That arrangement buys the link budget that makes mmWave work at all, and it introduces a failure mode that FR1 barely has: the beam pair can break while everything else — the cell, the security context, the bearers, the C-RNTI — remains completely valid.

Beam Failure Recovery exists because the alternative is absurd. Treating a blocked beam as a radio link failure would mean tearing down and rebuilding a connection, several seconds of work, because someone put a hand over an antenna for eighty milliseconds. BFR is a local repair: it changes which beam the PDCCH arrives on and changes nothing else.

CauseTypical timescaleWhat actually changesWhat it looks like
Hand or body blockage50-500 ms, often repeatingThe line of sight is attenuated by 20-30 dB; reflected paths may surviveL1-RSRP on the serving beam collapses while neighbouring SSB beams stay healthy. Highly correlated with a UE being picked up or put down.
UE rotation100 ms to a few secondsThe UE's own receive beam no longer points at the gNB, even though the gNB's transmit beam has not movedA beam switch to a different UE-side panel usually fixes it. Looks identical to blockage from the network side.
Vehicle or pedestrian passing100-300 ms, transientA moving obstacle crosses the Fresnel zoneShort, sharp, self-clearing. The main risk is a beamFailureInstanceMaxCount set low enough to trigger recovery for something that would have healed itself.
Walking round a cornerseconds, permanentThe direct path is gone for good; a reflected path or a different cell is now the best optionBFR may succeed on a reflected beam, then the UE needs a handover shortly afterwards. See the companion 22 Handover Overview document.
Panel or array faultpermanentOne transmit or receive direction is deadRepeated BFR on the same set of beams, always failing back to the same replacement. A hardware pointer, not a radio one.
gNB beam reconfigurationimmediateThe TCI state behind a CORESET was changed and the UE and gNB now disagree about which beam is activeBeam failure declared immediately after an RRCReconfiguration or a TCI State Indication MAC CE — a configuration fault masquerading as a radio one.

Table 1. Why beam pairs break. The middle two rows are the reason beamFailureInstanceMaxCount is tunable at all: recovery is cheap but not free, and a transient should be allowed to heal.

💡
Key Point

A beam failure is a link-level event with no RRC consequence. The UE does not change RRC state, does not re-derive keys, does not reset MAC, and does not lose a single RLC PDU that HARQ and ARQ would not have recovered anyway. It sends one preamble and carries on. That is the whole point, and it is why BFR belongs in a different mental category from RLF — see §3 and the companion 16 RLM and RLF document.

2. Beam Management in One Page: CORESETs, TCI States, Beam Pairs

To read a BFR log you need to know exactly what "the beam" means to the protocol, because the protocol never uses the word. What it configures is a chain:

  • A CORESET is where the UE looks for PDCCH — a set of PRBs and symbols. The companion 08 Scheduling document covers the structure.
  • Each CORESET has an active TCI state (Transmission Configuration Indication), which lists one or two reference signals and the type of quasi-colocation the UE may assume with each.
  • QCL Type-D is the spatial one: it says "receive this CORESET with the same spatial filter you used to receive that reference signal". The RS named in the Type-D relationship is, operationally, the beam.
  • So the PDCCH beam is the QCL Type-D source RS of the TCI state of the CORESET. A beam failure is the statement that those RSs have all become undecodable.
Implicit derivation of the BFD-RS setWhere the BFD-RS Set Comes From: Implicit DerivationTS 38.213 cl. 6 -- the implicit case, with no explicit RadioLinkMonitoringConfig for beam failureCORESETs the UE monitors for PDCCHCORESET 0SIB1 / initial BWPCORESET 1UE-specific SSCORESET 2UE-specific SSCORESET 3recovery SSActivated TCI state of each CORESETTCI state 3QCL Type-DTCI state 7QCL Type-DQCL Type-D source reference signalSSB #2periodic, 20 msCSI-RS res 7periodic, 20 msBFD-RS set the UE actually evaluatesBFD-RS set = { SSB #2 , CSI-RS resource 7 }derived from the CORESET TCI statesCORESET 0 is excluded: it is not associated with a UE-specific TCI state. The recovery search space's CORESET is alsoexcluded -- it is the CORESET the *response* arrives on, so including it would make the recovery depend on the beam thatjust failed.
Figure 1. The chain from CORESET to reference signal, and how the BFD-RS set falls out of it when no explicit list is configured. This is the most common deployment case: the network configures nothing and the UE tracks whatever beams its PDCCH is currently on.
⚠️
Common Pitfall

Because the implicit BFD-RS set follows the CORESET TCI states, changing a TCI state changes what the UE is monitoring for beam failure. A TCI State Indication MAC CE that moves a CORESET onto a beam the UE cannot actually receive will produce beam failure instances within a few RS periods, and the log will show beam failure immediately after a successful MAC CE. The cause is the CE, not the radio.

3. Three Nested Timescales: Beam, Cell, Connection

NR monitors the downlink at three levels at once, with three separate counters, three separate timers and three separate recovery procedures. They run concurrently on the same reference signals, and each is designed to be pre-empted by the faster one above it. Almost every confusing BFR log makes sense once you place each line at the right level.

Three Nested Timescales: Beam, Cell, ConnectionThree Nested Timescales: Beam, Cell, ConnectionBFD-RS 20 ms with n4; N310 n4 at 10 ms; T310 ms1000; T311 ms3000 -- illustrative valuesBeamBFRrecovered on SSB #5 at t = 95 ms -- still RRC_CONNECTED, same C-RNTI, same bearersCellRLM and RLFT310 stopped by N311 in-sync indications at t = 155 ms -- no RLF declaredConnectionre-establishmentnever reached08015530050070090010401200Time (ms)Green dashed = BFR complete at 95 ms; the first red dashed = T310 stopped at 155 ms; the second = where T310 wouldhave expired. Each layer is an order of magnitude slower than the one above it and is designed to be pre-empted by it.
Figure 2. One blockage, seen at all three levels. The out-of-sync indications and the beam failure instances come from the same measurements; the beam layer just reacts an order of magnitude sooner, and its success is what prevents the layers below from ever acting.
LevelWhat is being askedCounter and timerTypical detection timeRecoveryIf recovery fails
BeamCan I still receive PDCCH on the beam I am using?BFI_COUNTER against beamFailureInstanceMaxCount, windowed by beamFailureDetectionTimer20-200 msPick a candidate beam, send a contention-free preamble, get a PDCCH back (§8)Fall back to contention-based RACH; then, if that exhausts, RLF
CellIs this cell still usable at all?N310 out-of-syncs starts T310; N311 in-syncs stops itN310 x ~10 ms, then up to T310 (commonly 1 s)None — recovery is simply the arrival of N311 in-sync indicationsRLF is declared
ConnectionCan I get back onto some cell with my context intact?T311 for cell selection, then T301 for the reestablishment exchangesecondsRRCReestablishmentRequest on a suitable cell (§10)Fall back to RRCSetup from RRC_IDLE, with the release cause recorded

Table 2. The three levels. Note that only the beam level has an active recovery procedure that the UE initiates; the cell level recovers passively or not at all.

📘
Spec Detail

The layers share their input. RadioLinkMonitoringRS has a purpose field with values beamFailure, rlf and both — a single SSB can feed the BFI counter and the out-of-sync counter simultaneously, evaluated against different thresholds (§5). When you see out-of-sync indications and beam failure instances arriving together in a log, that is not duplication; it is one measurement being consumed by two state machines.

4. Beam Failure Detection: Which Reference Signals

Everything downstream depends on the BFD-RS set — the set of reference signals whose collective failure constitutes beam failure. There are two ways the UE ends up with one.

Implicit derivationExplicit configuration
When it appliesNo failureDetectionResourcesToAddModList is configured for this BWPRadioLinkMonitoringConfig provides failureDetectionResourcesToAddModList with purpose set to beamFailure or both
The set isThe periodic RSs that are the QCL Type-D sources of the active TCI states of the CORESETs the UE monitors for PDCCHExactly the RadioLinkMonitoringRS entries listed, each naming an ssb-Index or an NZP-CSI-RS-ResourceId
Tracks beam changes automatically?Yes — a TCI state update silently changes what is monitoredNo — the list must be updated by RRC when the serving beams change
Typical useThe default in most deployments; nothing to keep in stepWhen the network wants beam failure judged on a beam the PDCCH is not currently using, or wants to exclude a CORESET from the decision
Failure signatureBeam failure immediately after a TCI State Indication MAC CE (§2)Beam failure that never triggers, because the listed RS is a beam the UE can still hear while the PDCCH beam is dead

Table 3. Implicit and explicit BFD-RS derivation, TS 38.213 cl. 6. The two failure signatures at the bottom are mirror images and are the fastest way to tell which mode a UE is in when the configuration is not in front of you.

Two exclusions matter. CORESET 0 does not participate, because it is not associated with a UE-specific TCI state. And the CORESET carrying the recovery search space is excluded — including it would make the recovery path depend on the beam whose failure it is meant to repair. The number of RSs the UE must handle is capped, and the cap scales with the maximum number of SSBs in a half frame TS 38.213 cl. 5; maxNrofFailureDetectionResources bounds the ASN.1 list at 10.

💡
Key Point

The set is evaluated as an AND, not an OR. A beam failure instance is generated only when every RS in the BFD-RS set is worse than Q_out in the same evaluation period. A UE with two CORESETs on two different beams therefore does not declare beam failure when one of them is blocked — which is correct (it still has a working PDCCH) and frequently surprising when you are watching one beam's L1-RSRP fall off a cliff and nothing happens.

5. RLM and BFD: the Same Signals, Different Thresholds

Both radio link monitoring and beam failure detection ask the physical layer the same question — would a PDCCH sent to me right now decode? — and both answer it with a hypothetical PDCCH block error rate rather than a measured power. The UE takes the SINR it estimates from the reference signal, maps it through a reference PDCCH configuration defined in TS 38.133 (a specified DCI size, aggregation level and CCE count), and compares the resulting BLER against a threshold. It is a predicted decoding outcome, not an RSRP.

Beam failure detectionRadio link monitoring
Thresholds usedQ_out onlyQ_out and Q_in, with hysteresis between them
Default threshold valuesQ_out = 10% hypothetical PDCCH BLERQ_out = 10%, Q_in = 2% hypothetical PDCCH BLER
Selected byThe threshold configuration in force for the cellrlmInSyncOutOfSyncThreshold in ServingCellConfig selects the alternative threshold pair defined in TS 38.133 when present
What crossing it producesA beam failure instance indication to MAC, when all BFD-RS are worse than Q_outAn out-of-sync indication when the quality is worse than Q_out; an in-sync indication when it is better than Q_in
Consumed byBFI_COUNTER in MAC TS 38.321 cl. 5.17N310 / N311 counters in RRC TS 38.331
Indication rateBounded below by the BFD-RS periodicity and by the evaluation-period requirements of TS 38.133Commonly quoted as one indication per 10 ms for SSB-based RLM at FR1, again subject to TS 38.133 evaluation periods
ReactionActive: select a candidate beam and request recoveryPassive: start or stop T310 and wait

Table 4. The two mechanisms compared. The single most useful line is the last: BFD does something, RLM only counts.

⚠️
Common Pitfall

Because both are defined on a hypothetical PDCCH, a beam failure can be declared while L1-RSRP still looks acceptable. High interference, a bad SINR at good received power, or an aggregation level the CORESET cannot support will all produce BLER above Q_out with RSRP well above any threshold you would have picked by eye. Chasing a beam failure by looking only at RSRP is the most common wasted afternoon in FR2 debugging. Look at SINR and at PDCCH decode statistics.

6. The BFI Counter and beamFailureDetectionTimer

MAC does the counting TS 38.321 cl. 5.17. The rules are four lines long and the third one is the one that gets misremembered:

BFD counting, TS 38.321 cl. 5.17
on receiving a beam failure instance indication from lower layers:
    start or restart beamFailureDetectionTimer
    BFI_COUNTER := BFI_COUNTER + 1
    if BFI_COUNTER >= beamFailureInstanceMaxCount:
        if this Serving Cell is an SCell:  trigger BFR for that SCell
        else:                              initiate Random Access on the SpCell

on beamFailureDetectionTimer expiry:
    BFI_COUNTER := 0

on reconfiguration by upper layers of beamFailureDetectionTimer,
beamFailureInstanceMaxCount, or any BFD reference signal:
    BFI_COUNTER := 0

on successful completion of the Random Access procedure (SpCell):
    BFI_COUNTER := 0
    stop beamFailureRecoveryTimer, if configured
    consider Beam Failure Recovery successfully completed
Beam failure detection decision graphFrom One Bad Measurement to a Recovery RequestTS 38.321 cl. 5.17 and the BFR branch of TS 38.321 cl. 5.1.2PHY: every RS in the BFD-RS set isworse than Q_out this evaluation periodbeam failure instanceindication -> MACrestart beamFailureDetectionTimerBFI_COUNTER += 1beamFailureDetectionTimer expiry, orRS set / timer / max count reconfigured-> BFI_COUNTER = 0BFI_COUNTER >=beamFailureInstanceMaxCount?nowait for the nextindicationyesis this the SpCell?noSCell BFR: report with aBFR MAC CE on the SpCellyesany candidateBeamRSList entry withL1-RSRP > rsrp-ThresholdSSB?yesCFRA: the dedicated preambleand RO bound to that RSnoCBRA per rach-ConfigCommon -- recovery still possible,but with contention and no beam the gNB can inferThe reset is the part that is usually misremembered: BFI_COUNTER is cleared when beamFailureDetectionTimer EXPIRES,not when a single good measurement arrives. One good period among bad ones only postpones the timer.
Figure 3. The same rules as a decision graph. The dashed arrow is the reset path, and it is worth tracing carefully: nothing resets the counter except the timer expiring, a reconfiguration, or a completed recovery.
⚠️
Common Pitfall

BFI_COUNTER is not reset by a good measurement. A single good evaluation period produces no beam failure instance, which means the timer is not restarted — and that is the only way the counter ever gets cleared. So the timer must actually expire, which requires enough consecutive good periods to cover beamFailureDetectionTimer. With beamFailureDetectionTimer = pbfd2 (two RS periods), one good period among bad ones postpones the trigger and nothing more. Documentation that says "the counter resets if quality recovers" is describing the intent, not the mechanism.

BFI Accumulation Against beamFailureDetectionTimer: Two RunsBFI Accumulation Against beamFailureDetectionTimer: Two RunsBFD-RS periodicity 20 ms, beamFailureInstanceMaxCount n4, beamFailureDetectionTimer pbfd2 (= 2 RS periods = 40 ms)Run A -- recoversBFI instances12okok12okRun Abfd timer (pbfd2)restarted, runs 40 msrestartedRun B -- failsBFI instances1234Run Bbfd timer (pbfd2)irrelevant -- BFR already triggeredRun Boutcomecandidate + CFRAoperating on the new beam020406080100120140Time (ms)Khaki dashed at 60 ms: Run A's timer expires and BFI_COUNTER resets to 0. Red dashed at 66 ms: Run B reachesBFI_COUNTER = 4 = n4 and declares beam failure. Run A has four bad periods out of seven and never declares failure;the difference is not the count of bad periods -- it is whether two consecutive good periods ever let the timer expire.
Figure 4. Two runs with the same number of bad evaluation periods and opposite outcomes. Run A survives because it gets two consecutive good periods; Run B never does.
🧮
Worked Calculation

BFD-RS periodicity = 20 ms, beamFailureInstanceMaxCount = n4, beamFailureDetectionTimer = pbfd2 = 2 RS periods = 40 ms.

Run B — declares failure

t = 0 BFI -> BFI_COUNTER 1, timer restarted, would expire at 40

t = 20 BFI -> BFI_COUNTER 2, timer restarted, would expire at 60

t = 40 BFI -> BFI_COUNTER 3, timer restarted, would expire at 80

t = 60 BFI -> BFI_COUNTER 4 = n4 -> beam failure declared

Elapsed from the first instance: (4 - 1) x 20 = 60 ms

Run A — survives

t = 0 BFI -> 1, timer would expire at 40

t = 20 BFI -> 2, timer restarted, would expire at 60

t = 40 good -> no indication, timer keeps running

t = 60 good -> timer expires, BFI_COUNTER := 0

t = 80 BFI -> 1 again, counting starts over

Both runs saw four bad periods in the first 120 ms. The difference is purely whether two consecutive good periods ever appeared.

Sizing is a straight trade. Lowering beamFailureInstanceMaxCount from n4 to n2 halves detection time and doubles the rate of recovery attempts triggered by transients that would have cleared on their own — each of which costs a preamble, a response, and a beam switch that must then be switched back. Shortening the BFD-RS periodicity is the better lever when it is available, because it improves detection time without weakening the filter.

7. Candidate Beam Identification

Detecting failure is useless without somewhere to go. candidateBeamRSList in BeamFailureRecoveryConfig is the pre-agreed answer: a list of SSBs and CSI-RS resources, each already bound to a dedicated preamble index and a set of RACH occasions. That binding is what makes recovery fast and contention-free — the UE does not have to describe the beam it wants, because the preamble it sends says which one.

On beam failure, the UE evaluates L1-RSRP for the entries in the list and picks one whose L1-RSRP exceeds rsrp-ThresholdSSB TS 38.213 cl. 6. If several qualify, the choice is up to the UE. If none does, there is no contention-free option and the UE falls through to an ordinary contention-based Random Access using rach-ConfigCommon.

Outcome of the candidate searchWhat the UE sendsWhat the gNB learns from itCost
A candidate above rsrp-ThresholdSSB with a dedicated preambleThe dedicated ra-PreambleIndex on that candidate's RO, using that candidate's spatial filterBoth which UE and which beam — the index is UE-uniqueOne preamble, one response. No contention, no MSG3, no MSG4.
A candidate above the threshold but with no dedicated preamble configured for itContention-based preamble from rach-ConfigCommon, on the candidate's spatial filterThe beam, from the SSB-to-RO association; the UE only after contention resolutionFull 4-step RACH, with collision risk. See the companion 03 Random Access document.
No candidate above the thresholdContention-based preamble following normal SSB selection rulesWhatever the normal selection picked, which may be the beam that just failedFull 4-step RACH, and a real chance of recovering onto a beam that is about to fail again.
beamFailureRecoveryTimer already expiredContention-based preamble only — the dedicated resources are no longer usable for BFRAs aboveThe same as the row above, and a strong signal that the candidate list is stale (§10).

Table 5. What the candidate search produces. Only the first row is the procedure BFR was designed around; the other three are degraded modes that still work.

🧮
Worked Calculation

rsrp-ThresholdSSB is an RSRP-Range, an integer 0..127, not a dBm value. The mapping TS 38.133 is 1 dB per step:

level 0 -> RSRP < -156 dBm

level n -> (-157 + n) dBm <= RSRP < (-156 + n) dBm

level 127 -> RSRP >= -31 dBm

So a configured rsrp-ThresholdSSB = 56:

-157 + 56 = -101 dBm

A candidate SSB measured at -84 dBm is comfortably above it and qualifies; one at -104 dBm does not. Reading the raw ASN.1 integer as dBm — a very easy slip when scanning a decoded configuration — puts the threshold roughly 157 dB out.

⚠️
Common Pitfall

The candidate list is only as good as its last refresh. It is signalled per uplink BWP inside BeamFailureRecoveryConfig, and a UE that has moved since the list was written may find that none of the listed beams is above threshold — at which point BFR degrades to ordinary CBRA and loses most of its speed advantage. A high proportion of contention-based recoveries in a cell usually means the candidate lists are not being maintained, not that coverage is poor.

8. The Recovery Request: Contention-Free RACH on the Chosen Beam

For an SpCell, the recovery request is a Random Access procedure — the same procedure as initial access, entered from a different trigger and with the ambiguity removed. BeamFailureRecoveryConfig supplies its own rach-ConfigBFR (a RACH-ConfigGeneric: preamble format, power ramping, preambleTransMax, response window), its own rootSequenceIndex-BFR, and optionally its own ra-Prioritization so BFR preambles can ramp faster and retry sooner than ordinary access.

SpCell Beam Failure Recovery, End to EndSpCell Beam Failure Recovery, End to EndDetectionCandidate and requestResponseBookkeepingUE PHYUE MACgNBFR2, C-RNTI 0x71A4. CORESET 1 and 2 on TCI states sourced from SSB #2 and CSI-RS 7.candidateBeamRSList = SSB #2/#5/#9/#13 with dedicated preambles 52/53/54/55.the serving beam is blockedbeam failure instance indications 1 .. 4all BFD-RS worse than Q_out; counter hits n41beam failure declared on the SpCell-> initiate Random Access for BFRSSB #5 at -84 dBm, from candidateBeamRSListL1-RSRP above rsrp-ThresholdSSB -> selected2CFRA preamble 53 on SSB #5's ROSSB #5's spatial filter; index is UE-unique3preamble 53 names the UE and the beam-> answer on CORESET 3, QCL'd to SSB #5PDCCH to C-RNTI in recoverySearchSpaceIdCORESET 3, QCL'd to SSB #5 -- this is the ack4BFI_COUNTER = 0; stop beamFailureRecoveryTimer;BFR successfully completedTCI State Indication for PDCCH MAC CEmoves CORESET 1 and 2 onto the new beambeamFailureDetectionTimerbeamFailureRecoveryTimerThe recovery response is an ordinary PDCCH addressed to the UE's existing C-RNTI -- there is no BFR-specific message.The UE never left RRC_CONNECTED and never lost its security context or bearers.
Figure 5. SpCell BFR end to end. Step 3 carries two pieces of information in one transmission — the preamble index identifies the UE, and the spatial filter and RO identify the beam — which is why there is no MSG3 and no contention resolution.

Three details are worth pinning down because they are what distinguishes BFR RACH from any other RACH in a log:

  • The preamble is drawn from the CFRA pool, not the contention-based one. It is bound to a specific candidate RS by PRACH-ResourceDedicatedBFR, so detecting it tells the gNB the answer to both questions at once.
  • The UE keeps its C-RNTI. There is no TC-RNTI and no promotion; the UE was and remains a known, connected UE. This is the clearest way to tell BFR RACH from re-establishment RACH in a trace.
  • The response arrives on a different search space. recoverySearchSpaceId names a search space whose CORESET the gNB will point at the new beam — see §9.
⚠️
Common Pitfall

CFRA preambles for BFR are carved out of the same 64-preamble space as everything else in the cell, alongside the handover CFRA preambles. totalNumberOfRA-Preambles bounds the contention-based portion and the remainder is shared between mobility and beam recovery. A cell with heavy inbound mobility and aggressive FR2 beam management can run out, and the symptom is BFR silently degrading to contention-based access — the same symptom as a stale candidate list (§7), with a completely different fix. Check the preamble budget before the candidate lists.

9. The Response, and What the UE Assumes Afterwards

There is no BeamFailureRecoveryResponse message. The response is an ordinary PDCCH whose CRC is scrambled with the UE's existing C-RNTI, received in the search space given by recoverySearchSpaceId, within a window that opens a few slots after the preamble TS 38.213 cl. 6. Receiving it is the confirmation, and MAC then treats the Random Access procedure as successfully completed, clears BFI_COUNTER, and stops beamFailureRecoveryTimer.

The elegant part is what the UE assumes about the beam. Until it is given an explicit TCI state update, the UE assumes the CORESET associated with recoverySearchSpaceId is quasi-colocated with the candidate RS it selected TS 38.213 cl. 6. The gNB knows which candidate that was, because it knows which preamble it detected. So both ends switch to the new beam with no signalling at all — the beam change is carried entirely by the choice of preamble.

After a successful recoveryStateWhy
BFI_COUNTER
Reset to 0The procedure completed; counting starts afresh against the new beam
beamFailureRecoveryTimer
StoppedIts job was to bound the usefulness of the dedicated resources
C-RNTIUnchangedThe UE was never unidentified
Security context and keysUnchangedNo RRC procedure ran
Bearers, RLC and PDCP stateUnchangedBFR is invisible above MAC, apart from the delay it introduces
CORESET behind recoverySearchSpaceIdAssumed QCL'd to the selected candidate RSThe implicit beam switch; both ends infer it from the preamble
All other CORESETs and their TCI statesStill on the old, failed beam until updatedThe gNB must send a TCI State Indication MAC CE or an RRCReconfiguration. Until it does, only the recovery CORESET is usable.
candidateBeamRSList
Unchanged until reconfiguredIt may now list the beam that just failed and omit the one in use — which is why a refresh usually follows

Table 6. The UE's state after recovery. Row seven is the one that produces confused traces: recovery is complete, yet most of the UE's PDCCH configuration is still pointing at a dead beam.

🧮
Worked Calculation

Blockage at t = 0, BFD-RS periodicity 20 ms, beamFailureInstanceMaxCount = n4, PRACH configured every 10 ms:

t = 20 ms first beam failure instance (first evaluation after blockage)

t = 40 ms BFI_COUNTER = 2

t = 60 ms BFI_COUNTER = 3

t = 80 ms BFI_COUNTER = 4 = n4 -> beam failure declared

t = 82 ms candidate evaluated: SSB #5 at -84 dBm > -101 dBm threshold

t = 85 ms next RO for SSB #5 reached; CFRA preamble 53 transmitted

t = 89 ms PDCCH to C-RNTI in the recovery search space

Total: ~89 ms, of which 80 ms is detection and ~9 ms is the actual recovery.

Halving the BFD-RS periodicity to 10 ms takes the total to ~49 ms. Dropping beamFailureInstanceMaxCount to n2 as well takes it to ~29 ms. Making the RACH faster changes nothing worth measuring — the recovery half of the budget is already an order of magnitude smaller than the detection half.

How Long Recovery Takes, by MechanismHow Long Recovery Takes, by MechanismDetection = count x RS period; RLF detection = N310 x 10 ms + T310 -- illustrative, order of magnitude02004006008001000109BFR n1, 10 ms RS209BFR n2, 10 ms RS809BFR n4, 20 ms RS4009BFR n10, 40 ms RS1040250T310 path to RLFApproximate elapsed time (ms)Detection (ms)Recovery / reaction (ms)Detection dominates every row: tuning beamFailureInstanceMaxCount moves an order of magnitude, tuning the RACH does not.The gap between the BFR rows and the RLF row is two orders of magnitude, which is the whole point of having BFR at all.
Figure 6. Detection dominates every configuration, and the gap to the RLF path is two orders of magnitude. This is the quantitative version of the argument in §3.

10. When Recovery Itself Fails: the Route to RLF

beamFailureRecoveryTimer is widely described as the timer whose expiry causes radio link failure. It is not. Its documented effect TS 38.331 is narrower and more useful to know: on expiry, the UE stops using the contention-free BFR resources. The dedicated preambles and their beam bindings are no longer available, and any further recovery attempt is an ordinary contention-based Random Access.

The route to RLF runs through the RACH, not through this timer:

1. The UE keeps transmitting preambles, ramping power, up to preambleTransMax from rach-ConfigBFR (or from rach-ConfigCommon once the recovery timer has expired).

2. On reaching preambleTransMax, MAC issues a Random Access problem indication to RRC TS 38.321 cl. 5.1.4. MAC itself never declares a link failure.

3. RRC interprets that indication according to what triggered the RACH. For a BFR-triggered Random Access on the SpCell in RRC_CONNECTED, the interpretation is radio link failure.

4. RLF then runs its own course: T311, cell selection, RRCReestablishmentRequest, T301, and a fall back to RRCSetup if that fails. The companion 16 RLM and RLF document covers all of it.

💡
Key Point

In parallel, and independently, the same bad radio has been feeding out-of-sync indications into N310 and T310. In practice a UE whose beam recovery fails outright usually reaches RLF by T310 expiry before it exhausts preambleTransMax, because T310 started counting during the BFI accumulation. Both paths lead to the same place. Which one a given log shows depends entirely on the relative sizing of T310 and the BFR RACH budget — which is worth checking, because the two are usually configured by different people.

The distinction matters diagnostically. A log showing beamFailureRecoveryTimer expiry followed by a successful contention-based recovery is a working system whose candidate list was wrong. A log showing the recovery timer expiry followed by preamble exhaustion is a coverage or configuration failure. They look almost identical for the first 200 ms.

11. SCell Beam Failure Recovery (Rel-16): the BFR MAC CEs

Rel-15 defined beam failure recovery only for the SpCell, which left an obvious hole: an FR2 SCell aggregated onto an FR1 anchor is far more likely to lose its beam than the anchor is, and until Rel-16 the only remedies were to let it rot or to release it. Rel-16 fills the hole, and does it by report rather than by procedure — because the UE already has a working uplink on the SpCell, there is nothing a preamble could achieve that a MAC CE cannot.

SCell Beam Failure Recovery, by MAC CE (Rel-16)SCell Beam Failure Recovery, by MAC CE (Rel-16)DetectionCandidate and uplinkReport and repairUE PHYUE MACgNBSpCell healthy on FR1. The SCell with ServCellIndex 2, on FR2, loses its beam.There is no reason to RACH: the UE already has a working uplink on the SpCell.beam failure instances on SCell 2per-cell BFI_COUNTER hits the max count1beam failure on an SCell -> trigger BFR for SCell 2(no Random Access procedure is started)SSB #11 usable on SCell 2L1-RSRP above the SCell BFR threshold2Scheduling Request (BFR-specific SR)no UL grant available; PUCCH on the SpCell3uplink grant on the SpCellsized from the SR alone; the gNB cannot know why4BFR MAC CEbitmap bit C_2 set + { AC=1, Candidate RS ID=11 }5SCell 2 has failed, SSB #11 is usable-> retune SCell 2's CORESET TCI statesTCI State Indication MAC CE for SCell 2BFR cancelled; per-cell BFI_COUNTER = 06An SCell beam failure is a report, not a recovery procedure: the UE names the failed cell and a beam that would work,and the network does the rest. The SCell is never released and the SpCell is never touched.
Figure 7. SCell BFR. The interesting mechanism is the middle: the UE has something urgent to say and no grant, so it uses the Scheduling Request machinery — see the companion 10 BSR, PHR, SR document.
SpCell BFR (Rel-15)SCell BFR (Rel-16)
TriggerBFI_COUNTER for the SpCell reaches beamFailureInstanceMaxCountThe per-cell BFI_COUNTER for that SCell reaches its max count
What the UE doesInitiates a Random Access procedure on the SpCellTriggers BFR for that SCell — no Random Access at all
How the request travelsCFRA preamble bound to the candidate beamBFR MAC CE, or Truncated BFR MAC CE, on UL-SCH of the SpCell
If there is no uplink grantNot applicable — the preamble is the uplinkA Scheduling Request is triggered; a dedicated BFR SR configuration can be used so the request is distinguishable from a buffer-driven one
How the beam is namedImplicitly, by which preamble was detectedExplicitly, by the Candidate RS ID field in the CE
What if there is no usable candidateFall through to contention-based RACH (§7)Send the CE with AC = 0this cell has failed and I have nothing to offer
ResponsePDCCH to C-RNTI in recoverySearchSpaceIdA TCI State Indication MAC CE for that SCell, or an RRCReconfiguration; the SCell is not released
Effect on the rest of the UENone above MACNone — the SpCell and every other SCell are untouched

Table 7. The two procedures. The asymmetry is entirely about whether a working uplink already exists.

BFR MAC CE and Truncated BFR MAC CEBFR MAC CE and Truncated BFR MAC CETS 38.321 cl. 6.1.3 -- one-octet bitmap variant, abridgedbit76543210Oct 1SPC_7C_6C_5C_4C_3C_2 = 1C_1Oct 2AC=1RCandidate RS ID = 11 (index into the candidate list)Oct 3AC=0RCandidate RS ID -- reserved when AC = 0Octet 1 is the bitmap: SP for the SpCell, C_i for the SCell with ServCellIndex i. One candidate octet follows per bit thatis set, in ascending cell order. Octet 3 shows the AC = 0 form -- the cell has failed and the UE has no replacement beamto offer, which is a very different report from AC = 1.
Figure 8. The CE layout. The bitmap is the load-bearing part: it names every failed serving cell in one report, so the gNB learns the full extent of the problem even when the grant was too small to carry every candidate.
FieldWidthMeaningDiagnostic value
SP
1 bitBeam failure on the SpCell, and the presence of a candidate octet for itRarely set — the SpCell has its own RACH-based procedure. If you see it set, read §12: Rel-17 per-TRP operation can report an SpCell TRP failure this way.
C_i
1 bit eachBeam failure on the SCell with ServCellIndex i, and the presence of a candidate octet for itSeveral bits set at once means a whole FR2 panel or direction is gone, not one beam.
AC
1 bit1 = a candidate RS is being offered for this cell; 0 = no usable candidate and the ID field is reservedThe single most informative bit in the CE. AC = 0 means the UE has given up on that cell's candidate list, and the network should expect to reconfigure rather than retune.
Candidate RS ID
6 bitsIndex of the offered SSB or CSI-RS within that cell's candidate beam listCross-check against the configured list — an index the network does not recognise means the UE is acting on a configuration the network thinks it replaced.
R
1 bitReserved, set to zero--

Table 8. BFR MAC CE fields, TS 38.321 cl. 6.1.3. One candidate octet follows the bitmap for each bit that is set, in ascending serving cell order.

📘
Spec Detail

The Truncated BFR MAC CE exists for the case where the granted uplink cannot hold the full CE plus its subheader. It keeps the complete bitmap and drops candidate octets. That design choice is deliberate and worth appreciating: under pressure the protocol preserves which cells failed and sacrifices which beams would work, because the first is what the network must act on and the second it can ask for again.

12. Rel-17: Per-TRP BFR and Multi-CORESET-Pool Operation

Multi-TRP transmission, introduced in Rel-16, lets two geographically separated transmission points serve one UE, distinguished by CORESETPoolIndex values 0 and 1. That immediately breaks the Rel-15 BFD model, which treats the BFD-RS set as a single AND: with two TRPs, one can be completely blocked while the other is fine, and the AND means no beam failure is ever declared. The UE loses half its capacity and reports nothing.

Rel-17 fixes this by making detection and recovery per-TRP:

  • Two BFD-RS sets, one per CORESETPoolIndex, each with its own BFI_COUNTER and its own beamFailureDetectionTimer instance. Beam failure is now declared per TRP.
  • Two candidate beam lists, so a replacement can be found within the failed TRP's own beams rather than by moving everything to the surviving TRP.
  • Enhanced BFR MAC CE and Truncated Enhanced BFR MAC CE, which extend the Rel-16 report with the TRP (CORESET pool) the failure applies to, so one CE can describe a per-TRP failure on the SpCell as well as on SCells.
  • Partial recovery as a normal outcome. A UE can be operating with one TRP recovered and one TRP in a failed state, which is a state Rel-15 has no way to express and no way to log.
🔄
Release Delta

On a Rel-17 multi-TRP cell, the absence of beam failure indications is no longer evidence that both TRPs are healthy — a legacy single-set configuration will hide a dead TRP behind a live one, showing up only as halved throughput and a rise in HARQ retransmissions on one CORESET pool. If you are debugging capacity on multi-TRP, check whether per-TRP BFD is actually configured before you trust the beam failure counters.

13. Timers, Counters and Parameter Reference

ASN.1 fieldWhereValuesTypicalEffect and failure signature
beamFailureInstanceMaxCount
RLM confign1, n2, n3, n4, n5, n6, n8, n10n4 or n5How many beam failure instances declare failure. Too low: recovery for transients, with a beam switch that must be undone. Too high: detection so slow that T310 gets there first.
beamFailureDetectionTimer
RLM configpbfd1 .. pbfd10, in units of the BFD-RS periodpbfd2 or pbfd3The window the instances must fall inside. Too long and the counter never clears, so instances from unrelated fades accumulate; too short and a genuinely failing beam keeps resetting to zero and never triggers.
failureDetectionResourcesToAddModList
RLM config1 .. maxNrofFailureDetectionResources (10) entriesabsent (implicit)Explicit BFD-RS set. Each entry has a purpose of beamFailure, rlf or both (§4, §5).
candidateBeamRSList
BFR config1 .. maxNrofCandidateBeams entries of PRACH-ResourceDedicatedBFR4 to 8 beamsThe replacement beams, each bound to a preamble and RO. Stale lists are the commonest cause of BFR degrading to contention-based access.
rsrp-ThresholdSSB
BFR configRSRP-Range, 0..127 (1 dB steps)56 = -101 dBmQualifying bar for a candidate. Too high and no candidate ever qualifies; too low and the UE recovers onto a beam that fails again immediately.
recoverySearchSpaceId
BFR config
SearchSpaceId
one search spaceWhere the response is monitored. Its CORESET is excluded from the BFD-RS set and is the one the gNB retunes to the new beam (§9).
beamFailureRecoveryTimer
BFR configms10, ms20, ms40, ms60, ms80, ms100, ms150, ms200ms60 to ms150On expiry the UE stops using the contention-free BFR resources. It does not itself declare RLF (§10).
rach-ConfigBFR
BFR config
RACH-ConfigGeneric
short windowThe BFR RACH's own format, power ramping, preambleTransMax and response window. preambleTransMax here is what eventually produces the Random Access problem indication.
rootSequenceIndex-BFR
BFR config0..137distinct rootSeparate preamble sequence space for BFR, so BFR preambles cannot be confused with contention-based ones.
ra-Prioritization
BFR config
RA-Prioritization
often presentLets BFR preambles use a larger power ramping step and a higher scalingFactorBI, so recovery outruns ordinary access under load.
ssb-perRACH-Occasion, ra-ssb-OccasionMaskIndexBFR configas in RACH-ConfigCommon--BFR-specific SSB-to-RO association and occasion masking.
rlmInSyncOutOfSyncThreshold
ServingCell

Config

n1 or absentabsentSelects the alternative Q_in / Q_out threshold pair of TS 38.133 (§5).

Table 9. BFD and BFR parameters. RLM config = RadioLinkMonitoringConfig in ServingCellConfig; BFR config = BeamFailureRecoveryConfig, signalled per uplink BWP inside BWP-UplinkDedicated, which means a BWP switch can change the entire recovery configuration — including whether one exists at all.

⚠️
Common Pitfall

BeamFailureRecoveryConfig lives per BWP. A BWP switch — triggered by DCI, by a bandwidth part inactivity timer, or by RRC — can move a UE onto a BWP with a different candidate list, different dedicated preambles, or no BeamFailureRecoveryConfig at all. In the last case beam failure on the SpCell still triggers Random Access, but as contention-based access with no beam information for the gNB. A cell where BFR works well on the default BWP and badly after a BWP switch is almost always this.

14. Failure Modes and What Each One Means

FailureDetected byWhat the UE doesDiagnostic pointer
Beam failure declared for a transient that would have clearedNobody — the procedure is working as configuredRecovers onto a candidate beam, then usually switches backPairs of beam switches a few hundred milliseconds apart, in both directions. Raise beamFailureInstanceMaxCount or lengthen the BFD-RS period.
Beam failure never declared although one CORESET's beam is deadNobodyNothing — it still has a working PDCCH on the other beamHalved PDCCH capacity, rising HARQ retransmissions, and the BFD-RS set evaluated as an AND (§4). On Rel-17 multi-TRP, check whether per-TRP BFD is configured (§12).
BFI_COUNTER accumulating across unrelated fadesNobodyDeclares failure eventually, from instances minutes apartbeamFailureDetectionTimer set too long relative to the BFD-RS period. Look at the timestamps of the instances, not just the count.
No candidate above rsrp-ThresholdSSBUE MACFalls through to contention-based Random AccessRecovery takes 4-step RACH time instead of 2-message time. Either the candidate list is stale (§7) or the threshold is too high.
Candidate found but no dedicated preamble configured for itUE MACContention-based Random Access on the candidate's beamThe beam information survives (via SSB-to-RO association) but contention does not. Check candidateBeamRSList entries actually carry ra-PreambleIndex.
CFRA preamble sent, no PDCCH in the recovery search spaceUE MAC (response window)Ramps power and retries, up to preambleTransMaxEither the gNB is not detecting the BFR preamble — check rootSequenceIndex-BFR against neighbours — or recoverySearchSpaceId points at a CORESET the gNB is not using for the response.
beamFailureRecoveryTimer expiryUE MACStops using the contention-free BFR resources; further attempts are contention-basedNot itself a failure (§10). Followed by successful CBRA it means a wrong candidate list; followed by preamble exhaustion it means real trouble.
preambleTransMax reached on a BFR-triggered RACHMAC -> RRCRandom Access problem indication to RRC, which declares RLF on the SpCellThe genuine escalation. Correlate against T310, which was probably already running — whichever finishes first is what the log will blame.
Beam failure immediately after a TCI State Indication MAC CENobodyRecovers, possibly back onto the previous beamA configuration fault, not a radio one (§2). The implicit BFD-RS set followed the CE onto a beam the UE cannot receive.
BFR configured on one BWP and not anotherNobodyContention-based recovery on the BWP that lacks itRecovery behaviour that changes when the UE switches BWP. Compare BWP-UplinkDedicated across BWPs (§13).
SCell BFR triggered but no uplink grant arrivesUE MACKeeps the BFR pending and relies on the Scheduling RequestSR failures on the SpCell block SCell beam recovery entirely. Check sr-TransMax and the SR configuration in the companion 10 BSR, PHR, SR document.
AC = 0 in a BFR MAC CEgNBReports the failure with no candidateNot a UE fault. The SCell's candidate list needs replacing, or that direction is genuinely gone and the SCell should be released.

Table 10. BFR failure modes. As with DRX, most of them are detected by nobody: BFR has no failure report of its own, so every row is diagnosed from its side effects.

💡
Key Point

Two of these — a transient causing a recovery, and no candidate qualifying — are expected at some rate in any FR2 deployment and are not faults. Only their rate is informative. The two that always deserve attention are preamble exhaustion on a BFR RACH and beam failure that follows a TCI State Indication MAC CE, because the first costs a connection and the second is self-inflicted.

15. Configuration Reference (ASN.1)

Detection is configured in ServingCellConfig -> radioLinkMonitoringConfig; recovery is configured per uplink BWP in BWP-UplinkDedicated -> beamFailureRecoveryConfig. Abridged, with ... marking omitted members and extension markers:

RadioLinkMonitoringConfig ::= SEQUENCE {
    failureDetectionResourcesToAddModList
        SEQUENCE (SIZE(1..maxNrofFailureDetectionResources)) OF
                                        RadioLinkMonitoringRS   OPTIONAL,
    failureDetectionResourcesToReleaseList
        SEQUENCE (SIZE(1..maxNrofFailureDetectionResources)) OF
                                        RadioLinkMonitoringRS-Id OPTIONAL,
    beamFailureInstanceMaxCount     ENUMERATED {n1,n2,n3,n4,n5,n6,n8,n10}
                                                                OPTIONAL,
    beamFailureDetectionTimer       ENUMERATED {pbfd1,pbfd2,pbfd3,pbfd4,
                                               pbfd5,pbfd6,pbfd8,pbfd10}
                                                                OPTIONAL,
    ...
}

RadioLinkMonitoringRS ::= SEQUENCE {
    radioLinkMonitoringRS-Id        RadioLinkMonitoringRS-Id,
    purpose                         ENUMERATED {beamFailure, rlf, both},
    detectionResource               CHOICE {
        ssb-Index                       SSB-Index,
        csi-RS-Index                    NZP-CSI-RS-ResourceId
    },
    ...
}

Listing 1. Detection. purpose is the field that ties beam failure detection and radio link monitoring to the same reference signal (§5).

BeamFailureRecoveryConfig ::= SEQUENCE {
    rootSequenceIndex-BFR           INTEGER (0..137)            OPTIONAL,
    rach-ConfigBFR                  RACH-ConfigGeneric          OPTIONAL,
    rsrp-ThresholdSSB               RSRP-Range                  OPTIONAL,
    candidateBeamRSList
        SEQUENCE (SIZE(1..maxNrofCandidateBeams)) OF
                                    PRACH-ResourceDedicatedBFR  OPTIONAL,
    ssb-perRACH-Occasion            ENUMERATED {oneEighth, oneFourth,
                                                oneHalf, one, two, four,
                                                eight, sixteen} OPTIONAL,
    ra-ssb-OccasionMaskIndex        INTEGER (0..15)             OPTIONAL,
    recoverySearchSpaceId           SearchSpaceId               OPTIONAL,
    ra-Prioritization               RA-Prioritization           OPTIONAL,
    beamFailureRecoveryTimer        ENUMERATED {ms10, ms20, ms40, ms60,
                                               ms80, ms100, ms150, ms200}
                                                                OPTIONAL,
    ...,
    [[ msg1-SubcarrierSpacing       SubcarrierSpacing           OPTIONAL ]]
}

PRACH-ResourceDedicatedBFR ::= CHOICE {
    ssb                             BFR-SSB-Resource,
    csi-RS                          BFR-CSIRS-Resource
}

BFR-SSB-Resource ::= SEQUENCE {
    ssb                             SSB-Index,
    ra-PreambleIndex                INTEGER (0..63),
    ...
}

BFR-CSIRS-Resource ::= SEQUENCE {
    csi-RS                          NZP-CSI-RS-ResourceId,
    ra-OccasionList                 SEQUENCE (SIZE(1..maxRA-OccasionsPerCSIRS))
                                        OF INTEGER (0..maxRA-Occasions-1)
                                                                OPTIONAL,
    ra-PreambleIndex                INTEGER (0..63)             OPTIONAL,
    ...
}

Listing 2. Recovery, per uplink BWP. BFR-SSB-Resource is the binding that makes CFRA possible: one SSB index, one preamble index, and the gNB can read a beam out of a detected preamble.

16. 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.

16.1 The configuration the UE is given

[RRC-DL-DCCH] RRCReconfiguration -- RLM and BFR
RRCReconfiguration
 spCellConfig / spCellConfigDedicated                 -- ServingCellConfig
  radioLinkMonitoringConfig setup
   beamFailureInstanceMaxCount ............ n4
   beamFailureDetectionTimer .............. pbfd2     -- 2 x 20 ms = 40 ms
   failureDetectionResourcesToAddModList   (absent)   -- implicit set
  uplinkConfig / initialUplinkBWP
   beamFailureRecoveryConfig setup
    rootSequenceIndex-BFR ................. 91
    rach-ConfigBFR
     prach-ConfigurationIndex ............. 159
     preambleReceivedTargetPower .......... -104      -- dBm
     preambleTransMax ..................... n8
     powerRampingStep ..................... dB4
     ra-ResponseWindow .................... sl20
    rsrp-ThresholdSSB ..................... 56        -- -101 dBm (S7)
    candidateBeamRSList
     [0] ssb  { ssb 2,  ra-PreambleIndex 52 }
     [1] ssb  { ssb 5,  ra-PreambleIndex 53 }
     [2] ssb  { ssb 9,  ra-PreambleIndex 54 }
     [3] ssb  { ssb 13, ra-PreambleIndex 55 }
    recoverySearchSpaceId ................. 4         -- CORESET 3
    beamFailureRecoveryTimer .............. ms100
    ra-Prioritization
     powerRampingStepHighPriority ......... dB4
     scalingFactorBI ...................... zero

-- derived by the UE, not signalled:
--   BFD-RS set = { SSB 2, CSI-RS res 7 }   (QCL Type-D of CORESET 1 / 2)
--   candidate threshold = -101 dBm
--   detection budget = 4 instances x 20 ms = 80 ms

Listing 3. Detection and recovery configuration as it would appear decoded, with the derived values a good MAC trace prints alongside it.

16.2 A successful SpCell recovery

[PHY/MAC] SpCell BFR, happy path
-- C-RNTI 0x71A4 throughout, FR2, 120 kHz SCS

14:22:08.100  [PHY] BFD eval  SSB2 hyp-BLER 0.7%  CSI-RS7 hyp-BLER 0.9%
              -> both better than Q_out (10%), no indication
14:22:08.118  [PHY] serving beam obstructed (L1-RSRP SSB2 -78 -> -112 dBm)
14:22:08.120  [PHY] BFD eval  SSB2 hyp-BLER 41%  CSI-RS7 hyp-BLER 38%
              -> ALL BFD-RS worse than Q_out
              -> beam failure instance indication to MAC
14:22:08.120  [MAC] BFI_COUNTER = 1   beamFailureDetectionTimer (re)started
14:22:08.140  [PHY] BFD eval  both worse than Q_out -> indication
14:22:08.140  [MAC] BFI_COUNTER = 2   timer restarted
14:22:08.160  [MAC] BFI_COUNTER = 3   timer restarted
14:22:08.180  [MAC] BFI_COUNTER = 4 = beamFailureInstanceMaxCount (n4)
14:22:08.180  [MAC] beam failure declared on SpCell
              -> initiate Random Access, trigger = beamFailureRecovery
              -> start beamFailureRecoveryTimer (ms100)

14:22:08.182  [MAC] candidate beam evaluation, threshold -101 dBm
                    SSB 2  ... -112 dBm   below threshold
                    SSB 5  ...  -84 dBm   ABOVE  -> selected
                    SSB 9  ... -103 dBm   below threshold
                    SSB 13 ... -119 dBm   below threshold
14:22:08.182  [MAC] ra-PreambleIndex 53 (bound to SSB 5), CFRA
14:22:08.185  [PHY] PRACH sent, preamble 53, RO for SSB 5, 18.0 dBm
14:22:08.185  [MAC] monitoring recoverySearchSpaceId 4 (CORESET 3)
14:22:08.189  [PHY] PDCCH found in CORESET 3, DCI 1_1, CRC by C-RNTI 0x71A4
14:22:08.189  [MAC] Random Access successfully completed
              -> BFI_COUNTER = 0
              -> stop beamFailureRecoveryTimer
              -> Beam Failure Recovery successfully completed
              -- CORESET 3 assumed QCL'd to SSB 5 until told otherwise

14:22:08.204  [MAC-DL] TCI State Indication for UE-specific PDCCH MAC CE
                    CORESET 1 -> TCI state 11 (QCL-D source SSB 5)
                    CORESET 2 -> TCI state 12 (QCL-D source CSI-RS res 19)
              -- BFD-RS set now { SSB 5, CSI-RS res 19 }, implicitly

Listing 4. 89 ms from blockage to a decoded PDCCH on the new beam, 80 ms of it detection. The final MAC CE is what moves the rest of the UE's PDCCH configuration off the dead beam.

16.3 A run that recovers without declaring failure

[PHY/MAC] BFI accumulation that clears
14:31:55.400  [MAC] BFI_COUNTER = 1   timer started, expires 14:31:55.440
14:31:55.420  [MAC] BFI_COUNTER = 2   timer restarted, expires .460
14:31:55.440  [PHY] BFD eval  SSB2 hyp-BLER 6%  CSI-RS7 hyp-BLER 4%
              -> better than Q_out, NO indication
              -- note: BFI_COUNTER stays at 2, timer keeps running
14:31:55.460  [PHY] BFD eval  both better than Q_out, no indication
14:31:55.460  [MAC] beamFailureDetectionTimer EXPIRED -> BFI_COUNTER = 0
14:31:55.480  [PHY] BFD eval  both worse than Q_out -> indication
14:31:55.480  [MAC] BFI_COUNTER = 1   timer restarted
14:31:55.500  [PHY] BFD eval  both better than Q_out, no indication
14:31:55.520  [MAC] beamFailureDetectionTimer EXPIRED -> BFI_COUNTER = 0

-- five bad evaluation periods in 120 ms and no beam failure. Correct:
-- the counter only ever clears on timer expiry, and it cleared twice.

Listing 5. The reset mechanism in action. The line at .440 is the one to internalise: a good measurement does not reset the counter, it merely fails to restart the timer.

16.4 SCell recovery by MAC CE

[MAC] SCell BFR with the BFR MAC CE
14:47:31.010  [MAC] SCell 2 (FR2): per-cell BFI_COUNTER = 4 = n4
14:47:31.010  [MAC] beam failure on SCell -> trigger BFR for SCell 2
                    (no Random Access procedure initiated)
14:47:31.012  [MAC] SCell 2 candidate evaluation
                    SSB 11 ... -81 dBm   ABOVE threshold -> offer it
14:47:31.012  [MAC] no UL-SCH resource available -> trigger SR (BFR SR id 1)
14:47:31.014  [PHY-UL] PUCCH SR on the SpCell, SR id 1
14:47:31.020  [PHY-DL] PDCCH DCI 0_1 to C-RNTI 0x71A4, UL grant 12 octets

14:47:31.022  [MAC-UL] MAC PDU on the SpCell, 4 octets
              subheader  R=0 F=0 LCID=<BFR>  L=2
                BFR MAC CE
                  octet 1 = 0x02     -- SP=0, C_2=1, all other C_i=0
                  octet 2 = 0x8B     -- AC=1, R=0, Candidate RS ID = 11

14:47:31.034  [MAC-DL] TCI States Activation/Deactivation MAC CE, SCell 2
                    -> CORESETs on SCell 2 moved to a TCI state sourced
                       from SSB 11
14:47:31.034  [MAC] BFR for SCell 2 cancelled; per-cell BFI_COUNTER = 0

-- SpCell untouched throughout; SCell 2 never deactivated or released.

Listing 6. 24 ms from declaration to repair, most of it waiting for an uplink grant. Octet 1 = 0x02 is bit C_2 alone; octet 2 = 0x8B is AC = 1 with Candidate RS ID 11.

16.5 A failure path: no candidate, then preamble exhaustion

[MAC/RRC] BFR failure to RLF
15:02:44.300  [MAC] BFI_COUNTER = 4 = n4 -> beam failure on SpCell
15:02:44.300  [MAC] start beamFailureRecoveryTimer (ms100)
15:02:44.302  [MAC] candidate beam evaluation, threshold -101 dBm
                    SSB 2  ... -118 dBm     SSB 5  ... -121 dBm
                    SSB 9  ... -117 dBm     SSB 13 ... -124 dBm
              -> NO candidate above rsrp-ThresholdSSB
              -> fall back to contention-based Random Access
                 (rach-ConfigCommon, normal SSB selection)
15:02:44.305  [MAC] preamble 19 (CB pool), counter 1, SSB 9, 15.0 dBm
15:02:44.315  [MAC] ra-ResponseWindow expired, no RAR
15:02:44.333  [MAC] preamble 07, counter 2, 19.0 dBm
15:02:44.343  [MAC] ra-ResponseWindow expired, no RAR
15:02:44.400  [MAC] beamFailureRecoveryTimer expired
              -- contention-free BFR resources no longer usable;
              -- this is NOT an RLF and NOT a procedure failure
                       ... attempts 3..7 elided, all at 23.0 dBm (P_CMAX) ...
15:02:44.612  [MAC] preamble 44, counter 8 = preambleTransMax (n8)
15:02:44.622  [MAC] ra-ResponseWindow expired, no RAR
15:02:44.622  [MAC] -> Random Access problem indication to RRC
15:02:44.622  [RRC] RA problem, trigger was beamFailureRecovery, SpCell,
                    state RRC_CONNECTED  ->  RADIO LINK FAILURE

-- meanwhile, on the same bad radio:
15:02:44.240  [RRC] out-of-sync #1 ... #4  -> N310 (n4) reached
15:02:44.240  [RRC] start T310 (ms1000)
15:02:44.622  [RRC] T310 still running (382 ms elapsed) when RLF declared
              -- RLF came from the RACH, not from T310. With T310 = ms200
              -- the same trace would have blamed T310 instead.

Listing 7. The genuine escalation, with both routes to RLF visible. Which one the log records is a function of the relative sizing of T310 and the BFR RACH budget, not of the radio.

🔍
What You See In Logs

The last three lines are the reason to read a BFR failure and an RLF together rather than separately. Two independent state machines were racing the same fade, and the one that happened to finish first is the one that gets written down as the cause. If you are comparing RLF statistics across cells with different T310 values, you are partly comparing timer configurations rather than radio conditions.

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

ReleaseChangeWhy it matters when reading BFR
Rel-15SpCell BFR: implicit and explicit BFD-RS, BFI_COUNTER, beamFailureDetectionTimer, candidateBeamRSList, CFRA request, recoverySearchSpaceId, beamFailureRecoveryTimerThe baseline. Everything in §4 to §10 is Rel-15 and unchanged.
Rel-16SCell BFR with the BFR MAC CE and Truncated BFR MAC CE, a per-cell BFI_COUNTER, an SCell candidate list and a BFR-specific SRBeam failure can now be reported rather than recovered from, on a cell the UE is not using for control (§11).
Rel-16Multi-TRP with two CORESETPoolIndex valuesCreates the blind spot Rel-17 fixes: one dead TRP behind a live one, with the BFD-RS AND never triggering (§12).
Rel-16Enhancements to RA-Prioritization and BFR power rampingBFR preambles can legitimately ramp differently from ordinary access, so power figures in a RACH log are not comparable across triggers.
Rel-17Per-TRP BFR: BFD-RS set, BFI_COUNTER and candidate list per CORESET pool; Enhanced BFR and Truncated Enhanced BFR MAC CEsPartial failure becomes an expressible state. A UE can be half recovered (§12).
Rel-17Unified TCI framework — one indicated TCI state shared by PDCCH, PDSCH and uplinkThe chain in §2 shortens: the beam behind PDCCH is now often the same object as the beam behind everything else, so a BFR changes more at once.
Rel-17RedCap: reduced antenna and branch counts, relaxed RRMDetection is slower on RedCap UEs for the same configuration; do not compare BFR latency across device classes.
Rel-18L1/L2-triggered mobility (LTM) — cell switch on a MAC CE, with or without RACHBlurs the boundary in §3: a beam-level indication can now trigger a cell change without any RRC procedure, so 'beam event' no longer implies 'same cell'.
Rel-18Further multi-TRP and unified-TCI refinements; network energy saving features that change reference signal availabilityA BFD-RS whose transmission is suppressed for energy saving looks exactly like a blocked beam. Check cell DTX configuration before believing an FR2 blockage story.

Table 11. BFR-relevant changes by release. Confirm feature support against the UE capability exchange — see the companion 26 UE Capability document.

18. Reading BFR in Logs: A Checklist

1. Establish which BFD-RS set is in force, implicit or explicit (§4). If implicit, find the most recent TCI state change first — it silently redefined what the UE was monitoring, and a beam failure right after one is usually caused by it.

2. Check whether the failure was an AND across the whole set. A single beam's L1-RSRP collapsing produces no beam failure if another BFD-RS is still good. If you expected a failure and did not get one, this is why.

3. Read the BFI instance timestamps, not just the count. Instances spread across seconds mean beamFailureDetectionTimer is too long relative to the RS period; instances 20 ms apart are a real fade (§6).

4. Do not expect the counter to reset on a good measurement. Trace the timer, not the measurements. The counter clears only on timer expiry, on reconfiguration, or on a completed recovery.

5. Convert rsrp-ThresholdSSB from RSRP-Range to dBm before judging whether a candidate should have qualified: -157 + n (§7). The raw integer is not dBm.

6. Classify the recovery request. A dedicated preamble index from candidateBeamRSList means the full contention-free procedure worked. A contention-based preamble means either no candidate qualified, no dedicated preamble was configured, or beamFailureRecoveryTimer had expired — three different problems with three different fixes.

7. Look for the response in the right place. It is a PDCCH to the UE's existing C-RNTI in recoverySearchSpaceId, not a RAR and not a BFR-specific message. There is no TC-RNTI anywhere in a BFR trace.

8. Check what happened to the other CORESETs. Recovery only implies the recovery CORESET moved. Until a TCI State Indication MAC CE arrives, the rest of the UE's PDCCH configuration is still on the dead beam (§9).

9. When BFR fails, read T310 alongside it. Both were racing the same fade and either can produce the RLF. The one the log blames depends on timer sizing, not on the radio (§10, §16.5).

10. For SCells, read the AC bit. AC = 1 means retune; AC = 0 means the UE has nothing to offer and the candidate list or the SCell itself needs attention (§11).

11. On multi-TRP, confirm per-TRP BFD is configured before trusting any beam failure counter. A legacy configuration hides a dead TRP completely (§12).

19. Glossary

TermExpansionMeaning in this document
BFRBeam Failure RecoveryThe procedure that replaces a failed beam pair without touching RRC state.
BFDBeam Failure DetectionThe continuous PHY evaluation that produces beam failure instances.
BFD-RS set--The reference signals whose collective failure constitutes beam failure; derived implicitly from CORESET TCI states or configured explicitly (§4).
BFI_COUNTER
Beam Failure Instance counterMAC counter incremented per beam failure instance; cleared only on beamFailureDetectionTimer expiry, reconfiguration, or completed recovery (§6).
Q_out--The hypothetical-PDCCH BLER threshold, commonly 10%, above which a reference signal counts as failed (§5).
Q_in--The better threshold, commonly 2%, used only by radio link monitoring to generate in-sync indications.
Hypothetical PDCCH--A reference PDCCH configuration defined in TS 38.133 against which the UE predicts a BLER. RLM and BFD are both defined on it, not on RSRP.
TCI stateTransmission Configuration Indication stateThe binding from a CORESET to its reference signals and the QCL types assumed with them.
QCL Type-DQuasi-colocation type DThe spatial QCL relationship. Its source RS is, operationally, the beam (§2).
candidateBeamRSList
--Pre-agreed replacement beams, each bound to a dedicated preamble and RO so a detected preamble names a beam (§7).
CFRAContention-Free Random AccessThe recovery request flavour: a UE-unique preamble, so no MSG3 and no contention resolution.
recoverySearchSpaceId
--The search space the recovery response arrives in; its CORESET is excluded from the BFD-RS set.
ACAvailability of CandidateBit in the BFR MAC CE: 1 = a candidate beam is offered, 0 = the cell has failed with no replacement (§11).
CORESETPoolIndex
--The 0/1 tag that distinguishes two TRPs; the unit of per-TRP BFR in Rel-17 (§12).
SpCellSpecial CellThe PCell of the MCG or the PSCell of the SCG — the cell whose beam failure escalates to RLF.

20. References

  • 3GPP TS 38.321NR MAC protocol specification. Clause 5.17 (beam failure detection and recovery, BFI_COUNTER, the reset rules), 5.1.1 (Random Access initialisation and triggers, including beam failure recovery), 5.1.2 (Random Access resource selection, including the candidateBeamRSList branch), 5.1.4 (Random Access problem indication), 5.4.4 (Scheduling Request, used by SCell BFR), 6.1.3 (BFR and Truncated BFR MAC CE formats), Table 6.2.1-2 (UL-SCH LCID values).
  • 3GPP TS 38.213Physical layer procedures for control. Clause 6 (link reconfiguration: BFD-RS determination, candidate beam evaluation, the recovery response window and the post-recovery QCL assumption), clause 5 (radio link monitoring and the RLM-RS limits).
  • 3GPP TS 38.133Requirements for support of radio resource management. The hypothetical PDCCH used to define Q_in and Q_out, the threshold pairs, the beam failure and radio link monitoring evaluation periods, and the RSRP-Range to dBm mapping.
  • 3GPP TS 38.331RRC protocol specification. RadioLinkMonitoringConfig, RadioLinkMonitoringRS, BeamFailureRecoveryConfig, PRACH-ResourceDedicatedBFR, BFR-SSB-Resource, BFR-CSIRS-Resource, ServingCellConfig, BWP-UplinkDedicated, rlmInSyncOutOfSyncThreshold.
  • 3GPP TS 38.300NR overall description. The beam management and beam failure recovery overview, and where BFR sits relative to RLM and mobility.
  • 3GPP TS 38.214Physical layer procedures for data. TCI states, QCL types and L1-RSRP reporting, which supply the measurements BFR consumes.

Companion documents in this set

  • 02 Radio Frame Structure — SSB bursts and the half-frame structure the BFD-RS periodicities are built on.
  • 03 Random Access — the procedure BFR borrows for its request; the CFRA and preamble-budget material in §8 lives there in full.
  • 07 MAC PDU and Control Elements — the subheader and LCID framework the BFR MAC CEs use.
  • 08 Scheduling — CORESETs, search spaces and PDCCH monitoring; what a beam failure actually deprives the UE of.
  • 10 BSR, PHR, SR — the Scheduling Request mechanism SCell BFR depends on when it has no grant.
  • 11 DRXps-TransmitPeriodicL1-RSRP and why a power-saving UE can be slower to notice a beam problem.
  • 16 RLM and RLF — the cell-level layer of §3, and where a failed BFR ends up.
  • 20 Measurements and Events — L1-RSRP and L3 RSRP, and why the two disagree during a beam failure.
  • 22 Handover Overview / 25 Conditional HO and DAPS — what happens when the right answer is a different cell rather than a different beam.
  • 26 UE Capability — where SCell BFR, per-TRP BFR and unified TCI support is declared.