>
Home5G NRPHY — Physical LayerPDCCH Blind Decoding
📶 PHY — Physical LayerAdvanced

PDCCH Blind Decoding — CCE, Aggregation & Search Spaces in 5G NR

How the UE finds its DCI — REG, REG bundle and CCE, aggregation levels 1–16, interleaved vs non-interleaved CCE-to-REG mapping, search-space candidates and the blind-decode budget.

📚 3GPP-basedTS 38.211TS 38.213

The UE does not know the aggregation level. It does not know which candidate position was used. It does not know the DCI size. It does not know whether a grant was sent to it at all. So it decodes speculatively -- every candidate, at every configured size -- and lets the CRC decide, because the CRC carries the address as well as the checksum. Everything in this document follows from that: the RNTI-seeded hashing function that scatters candidates so two UEs rarely collide, the two independent per-slot budgets that bound how many guesses the UE can afford, the four-DCI-size limit that bounds the multiplier on those guesses, and the overbooking rules that resolve an over-configured UE by abandoning a search space without telling anyone. That last mechanism is the practical reason to read this document: a UE that has dropped a search space looks exactly like a UE with a coverage problem, and no counter on either side distinguishes them. This document works the hashing function through by hand for a real C-RNTI over three consecutive slots and four aggregation levels, counts a concrete configuration against both budgets, resolves an overbooking event to the specific searchSpaceId that stops being monitored, and computes the PDCCH false-alarm rate that a 24-bit CRC actually delivers under load.

Contents
  1. 01Why Blind Decoding Is Unavoidable
  2. 02What a Candidate Is, Exactly
  3. 03The Candidate-to-CCE Mapping, In Full
  4. 04The Hashing Function, Term by Term
  5. 05Worked: Two Slots, Four Aggregation Levels, One RNTI
  6. 06Candidate Collisions Between UEs
  7. 07The Two Per-Slot Budgets
  8. 08Counting Candidates and Counting CCEs
  9. 09The DCI Size Budget: Four Sizes, Three of Them C-RNTI
  10. 10Overbooking, and the Search Space That Stops Being Monitored
  11. 11Inside One Decode Attempt
  12. 12False Alarms, and DCI That Passes CRC but Makes No Sense
  13. 13Aggregation Level Selection, From the gNB Side
  14. 14Cross-Carrier Scheduling and the Per-UE Budget
  15. 15Rel-16 Span-Based Monitoring and the Per-Span Budget
  16. 16Parameter and Capability Reference
  17. 17Failure Modes, and What Each Looks Like in a Log
  18. 18ASN.1 Structures
  19. 19Worked Arithmetic
  20. 20Illustrative Message Traces
  21. 21Release Deltas: Rel-15 to Rel-18
  22. 22Reading Blind Decoding in Logs: A Checklist
  23. 23Glossary
  24. 24References

1. Why Blind Decoding Is Unavoidable

There is no downlink pointer. Nothing in NR tells a UE where its grant is before the grant arrives, because any such pointer would itself have to be found first, and the problem would only move. The UE therefore starts every monitoring occasion knowing four things it needs and not knowing any of them: which aggregation level the gNB chose, which candidate position within that level, which DCI size, and whether anything was transmitted to it at all.

It resolves this by guessing exhaustively. For every candidate in its list, at every DCI size it has been configured to expect, it demodulates the coded bits, runs a polar decoder, de-masks the CRC with each RNTI it owns, and checks the CRC. A CRC pass means this candidate carried a DCI for me. A CRC fail means nothing in particular -- noise, an empty candidate, or a perfectly good DCI addressed to a different UE. The UE cannot tell which, and does not need to.

💡
Key point

The CRC is doing two jobs at once, and this is the single idea the whole document rests on. It is an error detection code, as usual. It is also the address: the 16-bit RNTI is XORed into the last 16 bits of the 24-bit CRC before transmission TS 38.212 cl. 7.3, so a CRC that checks out after de-masking with your RNTI is simultaneously proof that the block decoded correctly and proof that it was meant for you. There is no separate destination field in a DCI. Look for one and you will not find it.

1.1 What the alternative would cost

Consider the design that avoids blind decoding: a fixed grant location per UE, signalled once at RRC setup. UE 1 always reads CCEs 0-1, UE 2 always reads CCEs 2-3, and so on. The UE then performs exactly one decode per occasion, and the whole of this document evaporates. It also breaks the cell in three separate ways:

What breaksWhyWhat it would cost in practice
Aggregation level becomes staticA fixed location has a fixed size, so the code rate is fixed. The gNB can no longer spend more CCEs on a UE that has moved to the cell edgeEither every UE is protected as if it were at the cell edge -- which throws away most of the CORESET -- or cell-edge UEs simply lose PDCCH
CORESET capacity becomes a hard UE countN reserved slots of L CCEs each means at most N UEs can ever be addressed in that CORESET, whether or not they have dataA 16-CCE CORESET with AL2 reservations serves exactly 8 UEs. A cell with 200 connected UEs cannot reserve anything
Statistical multiplexing disappearsPDCCH capacity is only affordable because most UEs are not scheduled in most slots. Reservation charges for every UE in every slotPDCCH would become the dominant overhead in the downlink instead of a few percent of it

Table 1. Why the fixed-location design is not merely inelegant. The hashing function in section 4 exists to give the scheduler freedom in all three dimensions at the price of decode attempts at the UE.

So the negotiation is explicit and it runs in both directions. The scheduler wants many candidates at many aggregation levels in many occasions, because each one is a degree of freedom. The UE wants few, because each one is a polar decode that must finish before the PDSCH it points at has been buffered. TS 38.213 clause 10.1 is where that negotiation is written down, and every limit in it is a limit on the UE's effort, enforced by the UE, invisible to the network.

1.2 What invokes this machinery

Blind decoding is not a procedure that starts and finishes. It runs continuously at every monitoring occasion the UE has, for as long as the UE is in RRC_CONNECTED Active Time -- and also in RRC_IDLE and RRC_INACTIVE, where the UE blind-decodes the paging search space for P-RNTI at every paging occasion. What varies is the candidate list, and it is recomputed:

  • Every slot, because the hashing recursion advances with the slot number -- the same configuration produces different CCE positions in consecutive slots (section 5).
  • Every monitoring occasion within a slot, because the budget is consumed per slot (Rel-15) or per span (Rel-16), and a second occasion in the same slot competes with the first.
  • At every BWP switch, because the CORESETs change, N_CCE,p changes, and therefore every candidate position changes. See the companion 30 CORESET and Search Space document for the configuration side.
  • At every C-RNTI change -- initial access, handover, re-establishment -- because the C-RNTI is the seed of the hashing recursion. A new C-RNTI relocates the UE's entire candidate set.
  • At SCell activation or deactivation, because the per-cell budget is apportioned across configured serving cells (section 14, and the companion 29 Carrier Aggregation document).
  • At search space set group switching (Rel-16) and after PDCCH skipping (Rel-17), both of which change which search spaces have occasions at all without any RRC message.
Figure 1. The loop, once. Note the two exits on the left: no candidate matched and no candidate was left to try are the same observable event, and neither produces a log line, a counter, or any uplink transmission.

2. What a Candidate Is, Exactly

A PDCCH candidate is a run of L control channel elements at consecutive CCE indices within one CORESET, at one monitoring occasion. L is the aggregation level and takes the values 1, 2, 4, 8 and 16. That is the whole definition, and three details in it are load-bearing.

DetailWhat it meansWhy it matters
Consecutive in CCE index, not in frequencyThe candidate occupies CCEs n, n+1, ... n+L-1. Where those CCEs sit in the resource grid depends on the CCE-to-REG mappingWith interleaved mapping a single candidate is scattered across the CORESET's whole bandwidth. The candidate is contiguous in index space only -- see companion 30 CORESET and Search Space section 5
Aligned to a multiple of LThe formula in section 3 multiplies by L at the end, so an AL4 candidate always starts at CCE 0, 4, 8, ...Aggregation levels therefore nest. An AL4 candidate is exactly two AL2 candidate positions, which is what makes the overlap in Figure 1 regular rather than arbitrary
Bounded by floor(N_CCE,p / L) positionsThere are only that many distinct places an AL-L candidate can go in a CORESET of N_CCE,p CCEsA 16-CCE CORESET has 2 AL8 positions and 1 AL16 position. Configuring aggregationLevel8 = n4 does not create four distinct positions -- it creates four candidate indices that alias onto two positions

Table 2. The three properties of a candidate that the arithmetic in the rest of this document depends on. The third is the one that surprises people, and section 5.4 works through what aliasing actually does to the candidate set.

📘
Spec detail

Aggregation level and candidate index are different things and the log field names do not always make that clear. L is the size of the PDCCH -- how many CCEs it occupies, and therefore its code rate. m is which candidate at that size -- an index from 0 to M_p,L - 1, where M_p,L is the nrofCandidates value for that aggregation level in that search space set. A UE configured with aggregationLevel2 = n6 has six AL2 candidates, m = 0 to 5, and the hashing function decides where each one lands.

2.1 Candidates per occasion, and where the number comes from

For one search space set s at one occasion, the candidate count is simply the sum of the five nrofCandidates values. Nothing scales it, nothing deduplicates it, and a candidate at an aliased position still counts:

Candidate count for one search space set, TS 38.331 nrofCandidates
candidates(s) = M_s,1 + M_s,2 + M_s,4 + M_s,8 + M_s,16

  nrofCandidates ::= SEQUENCE {
      aggregationLevel1   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
      aggregationLevel2   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
      aggregationLevel4   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
      aggregationLevel8   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
      aggregationLevel16  ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8}
  }

  worst case per search space set: 8 + 8 + 8 + 8 + 8 = 40 candidates
  which alone exceeds M_max,slot at every numerology except 15 kHz
  (44) -- and even there it leaves 4 for every other search space.

The enumeration deserves a second look. The values are n0, n1, n2, n3, n4, n5, n6 and n8 -- note that n7 does not exist, and note that a single search space set can legally be configured with 40 candidates, which is more than the entire per-slot budget at 30 kHz. The ASN.1 will not stop you. The UE will not report the problem. What happens instead is section 10.

Figure 2. One CORESET, one slot, four aggregation levels, sixteen candidates. The bottom row counts how many candidates cover each CCE: the total is 42 CCE-slots of decoding effort against 16 physical CCEs, which is why the CCE budget and the candidate budget in section 7 are different numbers measuring different things.

3. The Candidate-to-CCE Mapping, In Full

This is the formula that turns configuration into CCE indices. It is worth reading twice, because every symbol in it is doing something and the nesting of the two mod operations is easy to get wrong TS 38.213 cl. 10.1:

TS 38.213 cl. 10.1 -- PDCCH candidate to CCE mapping
The CCEs of PDCCH candidate m at aggregation level L, for search space
set s in CORESET p, in slot n:

                  /                                             \
   L  x   |  Y            +  floor( m x N_CCE,p )  +  n_CI  | mod  N_CCE,p
          |   p,n            (       L x M_max,p )          |      ------
                  \                                             /      L

        +  i          for  i = 0, 1, ... L-1

  written linearly:

    CCE(m,i) = L * ( ( Y_p,n
                       + floor( m * N_CCE,p / (L * M_max,p) )
                       + n_CI
                     ) mod floor( N_CCE,p / L )
                   ) + i

  N_CCE,p    total CCEs in CORESET p at this occasion
  M_max,p    nrofCandidates at level L for THIS search space set
             (the spec writes it M^(L)_s,max)
  m          candidate index, 0 .. M_max,p - 1
  n_CI       carrier indicator field value, 0 without cross-carrier
  Y_p,n      the hash (section 4). Zero for a common search space.
  i          which CCE within the candidate, 0 .. L-1

Listing 1. The candidate-to-CCE mapping. The inner floor(m x N_CCE,p / (L x M_max,p)) spreads the M candidates evenly across the CORESET; the outer mod floor(N_CCE,p / L) wraps them into the CORESET; the x L at the front aligns the result to an aggregation-level boundary.

3.1 Reading it as three independent stages

The formula composes three separable operations, and separating them makes hand-verification tractable.

StageThe termWhat it producesWhat changes it
1. Spreadfloor(m x N_CCE,p / (L x M_max,p))An offset, in units of L CCEs, that walks the M candidates roughly evenly through the CORESET. For N_CCE = 16, L = 2, M = 6 the offsets are 0, 1, 2, 4, 5, 6nrofCandidates and the CORESET size only. It does not depend on the UE, the slot, or the RNTI
2. Rotate+ Y_p,n + n_CI, then mod floor(N_CCE,p / L)Rotates the whole spread pattern around the CORESET by a per-UE, per-slot amountThe C-RNTI (through Y), the slot number (through Y), the CORESET index p (through A_p), and the CIF
3. Alignx L, then + iConverts a position index into the L consecutive CCE indices the candidate actually occupiesNothing -- it is pure arithmetic

Table 3. Stage 1 is common to every UE with the same configuration. Only stage 2 is per-UE, and only stage 2 changes from slot to slot. This is why two UEs with identical nrofCandidates have identically shaped candidate sets in different rotations.

📘
Spec detail

The two floor operations are not interchangeable and the outer one is the more commonly misread. floor(N_CCE,p / L) is the number of distinct positions available at that aggregation level, not the number of CCEs and not the number of candidates. With N_CCE,p = 16 that is 16 positions at AL1, 8 at AL2, 4 at AL4, 2 at AL8 and 1 at AL16. If M_max,p exceeds floor(N_CCE,p / L), distinct candidate indices necessarily alias onto the same CCEs -- and the aliased candidates still consume budget.

3.2 What the formula does not depend on

Three omissions are worth stating, because each one is a thing engineers reasonably expect to matter and it does not:

  • The DCI format and size. Candidate positions are identical whether the UE is looking for a 41-bit DCI 1_0 or a 60-bit DCI 1_1. The size is a separate axis of the search, multiplying the number of decode attempts without changing where they happen (section 9).
  • The symbol within the slot. Y_p,n is indexed by slot, not by occasion. Two monitoring occasions of the same search space set in the same slot -- symbol 0 and symbol 7, say -- compute the same candidate CCE indices. They differ only in which OFDM symbols carry them, which matters for the CCE count in section 8 but not for the hash.
  • Anything the gNB signals per-slot. There is no per-slot candidate hint, no DCI that says look here next time. Both ends compute the same positions independently from configuration that both already have, which is exactly why a C-RNTI mismatch is undetectable.

4. The Hashing Function, Term by Term

Y_p,n is the only per-UE, per-slot quantity in the mapping, and it is produced by a linear congruential recursion seeded with the UE's own RNTI TS 38.213 cl. 10.1:

TS 38.213 cl. 10.1 -- the candidate hashing recursion
  UE-specific search space set:

      Y_p,n  =  ( A_p  x  Y_p,n-1 )  mod  D

      Y_p,-1 =  n_RNTI               (the C-RNTI, and must be non-zero)
      D      =  65537                (a prime, 2^16 + 1)
      A_p    =  39827   for  p mod 3 = 0
                39829   for  p mod 3 = 1
                39839   for  p mod 3 = 2

      p      =  controlResourceSetId of the CORESET the search space
                set points at
      n      =  slot index within the frame, n_s,f^mu

  Common search space set:

      Y_p,n  =  0        for all p and all n

4.1 Why the hash is seeded with the RNTI

Because the alternative is coordination, and coordination costs signalling that would itself need a PDCCH. If every UE computed the same candidate positions, then in a CORESET with 8 AL2 positions the first eight UEs scheduled in a slot would collide with each other constantly, and the gNB would have to arbitrate every occasion explicitly. Seeding with n_RNTI scatters each UE's candidate set to a rotation of the CORESET that no other UE is likely to share, with no signalling at all -- both ends already know the C-RNTI, so both ends can compute the same rotation independently.

The corollary is the sharpest diagnostic in this document. The C-RNTI is an input to the address calculation, not just a label. If the UE and the gNB disagree about the C-RNTI by even one bit, they compute different Y_p,n and the UE searches a completely different rotation of the CORESET. Nothing detects this. The gNB transmits a valid PDCCH at a candidate position the UE never examines; the UE finds nothing at positions the gNB never used. Both sides are behaving correctly and the UE is simply unreachable. The event to look for is a C-RNTI change that one side applied and the other did not -- most often around handover (companion 22 Handover Overview) or contention resolution (companion 03 Random Access).

4.2 Why it advances every slot

Because a static per-UE rotation would make collisions permanent. Two UEs whose rotations happened to coincide would collide in every slot forever, and one of them would be systematically starved of AL2 candidates for the lifetime of the connection. Advancing the recursion once per slot means a collision in slot n says nothing about slot n+1: the pair of UEs re-randomises against each other 2000 times a second at 30 kHz. A collision becomes a transient loss of one scheduling opportunity rather than a persistent capacity fault.

📘
Spec detail

The recursion advances by slot index, and the slot index restarts at every frame boundary -- so Y_p,n is a function of the slot number within the frame, not a free-running counter. Implementations normally precompute the whole per-frame sequence: 10 values at 15 kHz, 20 at 30 kHz, 40 at 60 kHz, 80 at 120 kHz, per CORESET. That is why the hash costs essentially nothing at run time even though it looks expensive.

4.3 Why A_p depends on the CORESET index

Three multipliers, selected by p mod 3, so that a UE monitoring two CORESETs does not get correlated rotations in both. Without this, the same Y would apply to every CORESET and a UE unlucky in CORESET 1 would be unlucky in CORESET 2 in the same slot -- exactly the correlation the design is trying to break. With three multipliers the rotations in CORESETs 1 and 2 are effectively independent.

It also means something practical for hand-verification: you cannot reuse a computed Y across CORESETs. A UE with controlResourceSetId 1 and 2 has two separate recursions running, with multipliers 39829 and 39839, both seeded from the same C-RNTI. Getting this wrong is the commonest error when reconstructing a candidate set by hand from a configuration dump.

4.4 What n_CI does

n_CI is the value of the carrier indicator field in the DCI, and it is zero in every configuration without cross-carrier scheduling. When CrossCarrierSchedulingConfig is present and a cif-InSchedulingCell value is assigned, the scheduling cell's CORESET carries grants for several cells, and n_CI shifts the candidate positions per scheduled cell. The effect is that the candidates for SCell 2 and SCell 3, monitored in the same CORESET on the PCell, sit at different rotations rather than on top of each other.

Configurationn_CI valueConsequence for the candidate set
No cross-carrier scheduling0One candidate set per CORESET per slot. The common case
Self-scheduling in a cross-carrier-capable cell0The scheduled cell's own candidates keep the unshifted rotation, so self-scheduled grants and cross-carrier grants for other cells do not systematically collide
Cross-carrier scheduling of SCell kcif-InSchedulingCell of SCell k, 1 .. 7The candidate positions for SCell k's grants are rotated by that amount relative to the PCell's. Distinct CIF values therefore buy distinct candidate sets in one CORESET

Table 4. n_CI in the mapping formula. It is the CIF value, not the presence of the field, and it is the mechanism by which one CORESET can serve several serving cells without the candidate sets piling up. See the companion 29 Carrier Aggregation document for the CIF configuration itself.

4.5 Why the common search space uses Y = 0

Because that is the entire point of a common search space. A SI-RNTI-addressed DCI, a paging DCI, a RAR grant, a slot format indication -- these are addressed to a set of UEs, and the set members have different RNTIs or, in the case of a UE that has not yet been assigned one, no RNTI at all. There is no per-UE seed available, and if there were, using it would make the message unfindable by everyone except one UE.

So Y_p,n = 0 for common search spaces, the rotation term vanishes, and the candidate positions reduce to the spread pattern alone. Every UE monitoring that search space set with the same nrofCandidates computes identical CCE indices, in every slot, for the life of the cell. That is what makes it common.

💡
Key point

The two consequences of Y = 0 pull in opposite directions and both show up in loaded cells.

Common search space candidates are perfectly predictable, which is why a UE can find SIB1 knowing nothing but the MIB -- and why the RAR arrives where every contending UE can see it.

Common search space candidates are also perfectly contended: every UE in the cell has the same AL4 and AL8 positions in the common search space, so the common search space's CCEs are a shared resource with no randomisation to spread the load. A cell that pushes signalling through a common search space under load will block on those specific CCEs long before the CORESET as a whole is full.

5. Worked: Two Slots, Four Aggregation Levels, One RNTI

The configuration below is carried through the whole document. It is the same UE and the same CORESET as the traces in section 20, so any number here can be checked against any number there.

QuantityValueWhere it comes from
C-RNTI0x4C11 = 19473 decimalAssigned in MSG4; the seed Y_p,-1
CORESETcontrolResourceSetId = 1, 48 PRB x 2 symbolsPDCCH-Config of the active DL BWP
N_CCE,p48 x 2 / 6 = 16 CCEsPRB x duration / 6 -- companion 30 CORESET and Search Space section 2
A_p39829, because 1 mod 3 = 1TS 38.213 cl. 10.1
nrofCandidatesAL1 n6, AL2 n6, AL4 n2, AL8 n2, AL16 n0SearchSpace with searchSpaceId 1, UE-specific
Numerology30 kHz, mu = 1, 20 slots per framesubcarrierSpacing of the BWP

Table 5. The reference configuration. N_CCE,p = 16 is small enough to hand-check and large enough to show real aliasing behaviour at AL8 and AL16.

5.1 The hash, three slots

🧮
Worked calculation

Y_p,-1 = n_RNTI = 19473, A_p = 39829, D = 65537.

Y(1, 0) = (39829 x 19473) mod 65537

= 775590117 mod 65537

= 775590117 - 11834 x 65537

= 775590117 - 775564858 = 25259

Y(1, 1) = (39829 x 25259) mod 65537 = 47761

Y(1, 2) = (39829 x 47761) mod 65537 = 61444

Y(1, 3) = (39829 x 61444) mod 65537 = 35959

Only the residues matter, and only modulo the number of positions:

mod 16 (AL1) mod 8 (AL2) mod 4 (AL4) mod 2 (AL8)

Y(1,0) 11 3 3 1

Y(1,1) 1 1 1 1

Y(1,2) 4 4 0 0

That last table is where the interesting behaviour lives. Y changes dramatically from slot to slot -- 25259 to 47761 -- but the mapping only consumes it modulo floor(N_CCE,p / L), and at AL8 that modulus is 2. A 16-bit hash reduced modulo 2 is a coin flip, and at AL16 it is reduced modulo 1, which is not even that.

5.2 Slot n: the candidate positions

🧮
Worked calculation

Slot n, Y = 25259. n_CI = 0.

AL 1, M = 6, positions = floor(16/1) = 16

spread offsets floor(m x 16 / 6) = 0, 2, 5, 8, 10, 13

(25259 + offset) mod 16, with 25259 mod 16 = 11:

m=0: (11+0) mod 16 = 11 -> CCE 11

m=1: (11+2) mod 16 = 13 -> CCE 13

m=2: (11+5) mod 16 = 0 -> CCE 0

m=3: (11+8) mod 16 = 3 -> CCE 3

m=4: (11+10) mod 16 = 5 -> CCE 5

m=5: (11+13) mod 16 = 8 -> CCE 8

AL 2, M = 6, positions = floor(16/2) = 8

spread offsets floor(m x 16 / 12) = 0, 1, 2, 4, 5, 6

(25259 + offset) mod 8, with 25259 mod 8 = 3, then x 2:

m=0: 3 x 2 = CCE 6-7 m=3: (3+4) mod 8 = 7 -> CCE 14-15

m=1: 4 x 2 = CCE 8-9 m=4: (3+5) mod 8 = 0 -> CCE 0-1

m=2: 5 x 2 = CCE 10-11 m=5: (3+6) mod 8 = 1 -> CCE 2-3

AL 4, M = 2, positions = floor(16/4) = 4

spread offsets floor(m x 16 / 8) = 0, 2

25259 mod 4 = 3:

m=0: 3 x 4 = CCE 12-15

m=1: ((3+2) mod 4) x 4 = 1 x 4 = CCE 4-7

AL 8, M = 2, positions = floor(16/8) = 2

spread offsets floor(m x 16 / 16) = 0, 1

25259 mod 2 = 1:

m=0: 1 x 8 = CCE 8-15

m=1: ((1+1) mod 2) x 8 = 0 = CCE 0-7

Total: 6 + 6 + 2 + 2 = 16 candidates, covering 42 CCE-positions across 16 physical CCEs.

5.3 Slot n+1: the same configuration, different CCEs

🧮
Worked calculation

Slot n+1, Y = 47761. 47761 mod 16 = 1, mod 8 = 1, mod 4 = 1, mod 2 = 1.

AL 1: offsets 0, 2, 5, 8, 10, 13, base 1

CCE 1, 3, 6, 9, 11, 14 (slot n was 11, 13, 0, 3, 5, 8)

two positions in common: CCE 3 and CCE 11

AL 2: offsets 0, 1, 2, 4, 5, 6, base 1

positions 1, 2, 3, 5, 6, 7 -> CCE 2-3, 4-5, 6-7, 10-11, 12-13, 14-15

slot n was 6-7, 8-9, 10-11, 14-15, 0-1, 2-3

AL 4: offsets 0, 2, base 1 -> positions 1, 3 -> CCE 4-7 and 12-15

the same pair as slot n, in the opposite order of m

AL 8: offsets 0, 1, base 1 -> positions 1, 0 -> CCE 8-15 and 0-7

identical to slot n

Figure 3. The same search space set over three slots. AL1 and AL2 move substantially; AL4 permutes within the same pair of positions; AL8 does not move at all. The randomisation the hashing function provides is real at low aggregation levels and largely fictional at high ones -- which is the point of section 5.4.

5.4 The high-aggregation-level degeneracy

At AL8 in a 16-CCE CORESET there are two positions and the configuration asks for two candidates. The spread offsets are 0 and 1, and adding a hash modulo 2 permutes them. So the set of AL8 candidates is {CCE 0-7, CCE 8-15} in every slot, for every UE, forever. Only the labels m = 0 and m = 1 swap. At AL16 it is worse: one position, one candidate, no randomisation whatsoever.

⚠️
Common pitfall

This has a consequence people configure their way into repeatedly. Setting aggregationLevel8 = n4 in a 16-CCE CORESET does not give the scheduler four AL8 candidates. It gives four candidate indices whose spread offsets are floor(m x 16/32) = 0, 0, 1, 1 -- two pairs of exact duplicates. The UE dutifully counts all four against M_max,slot, decodes all four at every configured DCI size, and gains nothing. You have spent 4 candidates of a 36-candidate budget to buy 2 positions. Check nrofCandidates at high aggregation levels against floor(N_CCE,p / L) before believing the configuration does what it looks like it does.

The general rule: the hashing function randomises usefully when M_p,L is small relative to floor(N_CCE,p / L), and degenerates as the two approach each other. At AL1 with 6 candidates in 16 positions there is real freedom. At AL8 with 2 candidates in 2 positions there is none. This is one of several reasons a CORESET sized for AL16 -- 32 CCEs or more -- behaves qualitatively better under load than a 16-CCE one, even at the same total capacity per slot.

6. Candidate Collisions Between UEs

Two UEs collide when a CCE that one UE's candidate occupies is also occupied by a candidate of the other, at the same occasion, and the gNB wants to schedule both. It cannot: a CCE carries one PDCCH. So one of the two UEs is not scheduled in that occasion, and the loss is a PDCCH blocking event rather than a decoding failure.

6.1 The birthday framing

The right intuition is the birthday problem, not a per-pair collision probability. With P = floor(N_CCE,p / L) positions at aggregation level L and k UEs each needing one candidate at that level, the probability that all k get distinct positions is the familiar falling factorial, and it collapses much faster than people expect:

🧮
Worked calculation

AL 2 in a 16-CCE CORESET: P = 8 positions.

P(no collision among k UEs) = 8!/(8-k)! / 8^k

k = 2: 8/8 x 7/8 = 0.875

k = 3: x 6/8 = 0.656

k = 4: x 5/8 = 0.410

k = 5: x 4/8 = 0.205

k = 6: x 3/8 = 0.077

k = 8: x 2/8 x 1/8 = 0.0024

By four UEs contending for AL2 positions in one occasion, a collision is more likely than not. This is with the full candidate set, six candidates each -- the numbers above are for one candidate each and are therefore optimistic as a per-candidate figure and pessimistic as a per-UE figure, because a UE with six AL2 candidates only fails when all six are blocked.

That last caveat is what makes nrofCandidates worth spending budget on. A UE with one AL2 candidate is blocked whenever that one position is taken. A UE with six is blocked only when all six are taken, which under moderate load essentially never happens. The candidate count is a blocking-probability knob, and it is the only one the configuration offers.

6.2 A real collision, computed

Take a second UE in the same cell, C-RNTI 0x5A2F = 23087, monitoring the same search space configuration on the same CORESET.

🧮
Worked calculation

UE A: C-RNTI 0x4C11, Y(1,n) = 25259, 25259 mod 8 = 3

UE B: C-RNTI 0x5A2F, Y(1,n) = (39829 x 23087) mod 65537 = 48013,

48013 mod 8 = 5

AL2 candidate start CCEs, slot n:

UE A: 6, 8, 10, 14, 0, 2

UE B: 10, 12, 14, 2, 4, 6

Shared positions: CCE 6, 10, 14 and 2 -- four of six

Exclusive to A: CCE 8, 0

Exclusive to B: CCE 12, 4

The gNB can still schedule both, at AL2, in this occasion: A on CCE 8-9 and B on CCE 12-13, for instance. It has lost most of its freedom to place them, but not the ability to place them.

One slot later, Y(1,n+1) = 47761 for A and 5654 for B:

UE A: 2, 4, 6, 10, 12, 14

UE B: 12, 14, 0, 4, 6, 8

shared: 4, 6, 12, 14 -- a different four, and the exclusive

positions have moved to 2, 10 for A and 0, 8 for B.

Two things to take from that. First, the overlap is large -- four of six -- and this is normal, not unlucky: with 8 positions and 6 candidates each, two UEs must share at least four. Second, the overlap changes membership every slot, so no particular candidate is chronically unavailable to either UE. The hashing function does not prevent collisions; it prevents them from being persistent.

6.3 What the gNB does about it

Every scheduler implementation has a CCE allocator that runs after the per-UE scheduling decisions and before PDCCH assembly. The details are not specified, but the shape is forced by the arithmetic:

  1. Compute each selected UE's candidate CCE sets for this occasion, at the aggregation level link adaptation asked for.
  2. Order the UEs -- typically by priority, then by constrainedness: a UE needing AL8 has two positions and must be placed before a UE needing AL1 with sixteen.
  3. Place each UE greedily into a free candidate. On failure, either drop the UE from this occasion or retry at a lower aggregation level if the link budget allows it.
  4. Any UE still unplaced is not scheduled in this occasion. Its data waits for the next one, which is a fresh rotation of every candidate set.
💡
Key point

A heavily loaded cell loses PDCCH capacity to collisions, not to coding. The arithmetic makes this concrete: a 16-CCE CORESET has 108 x 16 = 1728 coded bits per occasion, enough for twenty AL1 PDCCHs' worth of information at a sane code rate -- but there are only 16 AL1 positions and the collision probability among 16 randomly-placed UEs is essentially 1. In practice a 16-CCE CORESET schedules six to ten UEs per occasion before blocking becomes the dominant loss, well short of what its raw capacity suggests. When PDCCH blocking appears in statistics before PRB utilisation does, the answer is a bigger CORESET or more occasions, not a lower code rate.

SymptomCollision-driven?How to tell them apart
Grants delivered but PDSCH BLER highNoPDCCH found fine; this is a PDSCH link adaptation problem. See companion 34 Link Adaptation
Scheduling latency rises with cell load, PDCCH BLER flatYesThe classic signature. UEs are being deferred to later occasions because candidates were unavailable, not because PDCCH failed
PDCCH BLER rises for one UE onlyNoOne UE's aggregation level is too low for its channel -- an aggregation-level selection problem (section 13)
High-AL UEs starve while low-AL UEs are fineYes, structurallyAL8 and AL16 have 2 and 1 positions in a 16-CCE CORESET. Cell-edge UEs are competing for almost nothing (section 5.4)
Blocking concentrated on specific CCE indicesYes, in the CSSCommon search space candidates use Y = 0, so every UE has the same positions there (section 4.5)

Table 6. Distinguishing candidate collisions from the failure modes they resemble. Collision loss scales with load and leaves PDCCH BLER unchanged, which is the discriminator worth remembering.

7. The Two Per-Slot Budgets

There are two limits, they are independent, and a configuration can pass one and fail the other. Almost everyone remembers the first and forgets the second, which is why a configuration review that only checks candidate counts can still produce a UE that drops search spaces TS 38.213 cl. 10.1.

LimitSymbolWhat it countsWhat it bounds in the UE
Candidate limitM_max,slotMonitored PDCCH candidates, summed over all search space sets with an occasion in this slot, per serving cellPolar decoder throughput. Every candidate is at least one decode attempt, and more than one if several DCI sizes apply
CCE limitC_max,slotNon-overlapping CCEs, summed over all CORESETs monitored in this slot, per serving cellChannel estimation effort. Every distinct CCE the UE might decode has to have its DMRS extracted and a channel estimate formed, whether or not a DCI is there

Table 7. The two budgets. They are enforced by the UE, per slot, per serving cell, and TS 38.213 Tables 10.1-2 and 10.1-3 give the values per numerology.

muSCSM_max,slotC_max,slotWhy these values
015 kHz4456A 1 ms slot gives the decoder the most time, so the candidate budget is the highest of the four
130 kHz3656Half the slot duration, so 18% fewer candidates -- but the same CCE budget, because channel estimation is bounded by memory and correlator width rather than by time
260 kHz2248Both limits fall. 60 kHz FR1 is rare; 60 kHz FR2 is used for URLLC
3120 kHz2032FR2. Twenty candidates per slot is very little, which is why FR2 search space configurations are sparse and aggregation levels are high

Table 8. Per-slot, per-serving-cell PDCCH monitoring limits. The 15-to-30 kHz row pair is the instructive one: M_max drops and C_max does not, because the two limits are bounding different hardware.

Figure 4. Both budgets against numerology. The ratio C_max / M_max rises from 1.27 at 15 kHz to 1.6 at 120 kHz, so at high numerology it is nearly always the candidate limit that binds first -- the reverse of what many people assume from the larger absolute number.

7.1 Why two limits and not one

Because they bound two different pieces of silicon on two different timelines. Channel estimation happens before the UE knows which candidates matter: the DMRS in a CORESET is spread across all of it, and the UE must estimate the channel over every CCE it might decode, in the few tens of microseconds between the CORESET symbols ending and the decoder needing input. Polar decoding happens afterwards and is a sequential-ish, iterative workload with a different bottleneck.

The distinction also explains the counting rules, which otherwise look arbitrary. Candidates are counted with multiplicity, because each one is a separate decode. CCEs are counted without multiplicity -- hence "non-overlapping" -- because two candidates sharing a CCE share its channel estimate. In Figure 1 the sixteen candidates cover 42 CCE-positions but only 16 distinct CCEs, so they cost 16 against C_max,slot and 16 against M_max,slot. Change nrofCandidates to AL8 n2 only and you cost 2 candidates and still 16 CCEs.

📘
Spec detail

Both limits apply per serving cell in the single-cell case, and the figures in the table are the single-cell values. With carrier aggregation the accounting changes shape entirely -- the UE reports a total blind-detection capability and the per-cell limits are scaled down from it. Section 14 works that through, and it is a routine cause of "the configuration was fine on the PCell alone".

8. Counting Candidates and Counting CCEs

Both counts are easy to get wrong in the same two ways: forgetting that a search space set with two occasions in a slot is counted twice, and getting the definition of "non-overlapping" wrong. Here are both rules, precisely.

8.1 Counting candidates

Candidate counting against M_max,slot
M_slot = sum over every (search space set s, occasion o) pair in this
         slot of  ( M_s,1 + M_s,2 + M_s,4 + M_s,8 + M_s,16 )

  counted with multiplicity:
    - the same search space set at two occasions counts twice
    - two search space sets on the same CORESET count separately
    - a candidate that aliases onto another candidate's CCEs
      still counts (section 5.4)

  NOT multiplied by the number of DCI sizes. A candidate monitored
  at two DCI sizes is two decode attempts but ONE monitored candidate.
  The DCI size multiplier is bounded separately, by the four-size
  rule in section 9.

That last paragraph is the subtle one and it is worth being explicit about. M_max,slot = 36 at 30 kHz does not mean 36 decode attempts. It means 36 candidates, each of which may be attempted at up to four different DCI sizes, so the worst-case attempt count is considerably higher. The specification bounds attempts indirectly, by bounding sizes -- which is exactly why the four-size limit exists and why it is not negotiable.

8.2 Counting non-overlapping CCEs

Two candidates' CCEs are the same CCE for counting purposes only if all three of these match: the CORESET, the first symbol of the monitoring occasion, and the CCE index. Change any one and it is a separate CCE with a separate channel estimate.

Two candidates that ...Counted asBecause
are in the same CORESET, same occasion, same CCE indexone CCEOne set of DMRS, one channel estimate, shared
are in the same CORESET at the same CCE index but different first symbolstwo CCEsDifferent OFDM symbols carry different DMRS. The estimate cannot be reused, so this is the rule that makes sub-slot monitoring expensive
are in different CORESETs at the same CCE indextwo CCEsDifferent PRBs, different DMRS scrambling, possibly different beams -- unrelated estimates
belong to different search space sets but land on the same CORESET, occasion and CCEone CCEThe estimate is a property of the resource, not of the search space set. Two search space sets on one CORESET are cheap in CCE terms and expensive in candidate terms

Table 9. The non-overlapping rule. The second row is the one that bites: adding a second monitoring occasion in the same slot on the same CORESET duplicates the entire CORESET's CCE cost.

8.3 Both counts for the reference configuration

🧮
Worked calculation

mu = 1, so M_max,slot = 36 and C_max,slot = 56.

CORESET 1 = 16 CCEs. CORESET 2 = 18 PRB x 1 symbol = 3 CCEs.

Search space sets with an occasion in slot 2:

SS 1 USS, CORESET 1, symbol 0

AL1 n6 + AL2 n6 + AL4 n2 + AL8 n2 = 16 candidates

SS 2 USS, CORESET 1, symbols 0 and 8 (two occasions)

(AL1 n4 + AL2 n2 + AL4 n1) x 2 = 14 candidates

SS 4 CSS type3, CORESET 1, symbol 0

AL2 n2 + AL4 n1 = 3 candidates

SS 3 CSS, CORESET 2, symbol 0

AL1 n1 + AL2 n1 = 2 candidates

M_slot = 35 <= 36 OK

Non-overlapping CCE buckets:

(CORESET 1, symbol 0): SS 1 + SS 2 occ.1 + SS 4

SS 1's AL8 candidates alone cover all 16 CCEs -> 16

(CORESET 1, symbol 8): SS 2 occ.2

Y(1,2) = 61444; AL1 {4,8,12,0}, AL2 {8-9, 0-1},

AL4 {0-3} -> union {0,1,2,3,4,8,9,12} -> 8

(CORESET 2, symbol 0): SS 3, 3-CCE CORESET, all of it -> 3

C_slot = 27 <= 56 OK

One candidate of headroom on M, twenty-nine on C. Adding a single AL1 candidate anywhere in this configuration puts it over the candidate budget while the CCE budget is still less than half used.

8.4 Configurations that pass one limit and fail the other

Both directions occur in real configurations, and they are diagnosed completely differently, so it is worth having a concrete example of each in mind.

🧮
Worked calculation

Case A -- M fails, C passes. Five UE-specific search space sets, all on the same 8-CCE CORESET at symbol 0, each configured aggregationLevel1 = n8.

candidates = 5 x 8 = 40 > 36 FAILS

non-overlapping CCEs = 8 (one bucket, one CORESET, one symbol)

= 8 <= 56 passes easily

Diagnosis: too many low-aggregation-level candidates. Cheap to fix -- reduce nrofCandidates, and the CCE cost does not change at all.

Case B -- C fails, M passes. Three 16-CCE CORESETs, each with one search space set configured aggregationLevel8 = n2 and nothing else, each monitored at two symbol positions in the slot.

candidates = 3 CORESETs x 2 occasions x 2 = 12 <= 36 passes

CCE buckets = 6, each covering all 16 CCEs (two AL8 candidates cover a 16-CCE CORESET completely)

non-overlapping CCEs = 6 x 16 = 96 > 56 FAILS

Diagnosis: too many CORESET-occasions, not too many candidates. Reducing nrofCandidates does nothing here -- you must remove an occasion or a CORESET.

⚠️
Common pitfall

Case B is the one that gets missed in configuration review, because twelve candidates against a limit of thirty-six looks comfortable and nobody adds up CCE buckets by hand. It arises naturally from a reasonable-sounding intent: three beams, each with its own CORESET, each monitored twice per slot for latency. The result is a UE that drops its highest-numbered search spaces every slot, so the third beam's CORESET is never monitored at all -- and a beam that is configured, transmitted on, and unmonitored looks exactly like a beam that has failed.

9. The DCI Size Budget: Four Sizes, Three of Them C-RNTI

The number of DCI sizes the UE monitors on a serving cell is limited separately from the number of candidates, and the limit is small TS 38.212 cl. 7.3.1.0:

  1. At most four different DCI sizes may be monitored per serving cell.
  2. Of those, at most three may be sizes for DCI scrambled by C-RNTI.

The reason is the multiplier in section 8.1. Every extra size multiplies the decode attempts across the entire candidate set, and unlike candidates it does so without any corresponding gain in scheduling freedom -- the gNB does not gain a placement option from a fourth DCI size, it gains a message type. So the specification rations sizes hard and then goes to considerable lengths to make configurations fit.

9.1 Why sizes, and not formats

Because the UE decodes to a length, not to a format. A polar decoder needs to know how many bits it is producing before it starts; the format is then inferred from which search space the candidate was in, from the RNTI that de-masked the CRC, and from the format-identifier bit in the payload. Two formats of the same length cost one size and are disambiguated after the fact:

FormatsSame size?Cost against the four-size budget
DCI 0_0 and DCI 1_0 in a common search spaceYes, by constructionOne size. The size-alignment procedure pads the shorter one; the identifier bit distinguishes uplink from downlink
DCI 0_1 and DCI 1_1 in a UE-specific search spaceNo, in generalTwo sizes. Their field sets differ substantially, and step 2 of the alignment procedure adds a padding bit specifically to prevent them colliding with the 0_0/1_0 size
DCI 2_0 (SFI, SFI-RNTI)NoOne size, but not a C-RNTI size, so it consumes the fourth slot without touching the three-C-RNTI limit
DCI 2_1 (pre-emption, INT-RNTI)NoAnother non-C-RNTI size. Configuring both 2_0 and 2_1 alongside three C-RNTI sizes is five sizes and does not fit
DCI 1_0 with SI-RNTI, P-RNTI, RA-RNTIYes, all the same sizeShares the common-search-space 1_0 size. Different RNTIs at the same size are free

Table 10. What costs a size and what does not. Different RNTIs at the same payload size are free; the same RNTI at two payload sizes is not. This is the opposite of most engineers' first guess.

9.2 Size alignment and zero padding

The DCI sizes are not chosen; they fall out of the configuration. A DCI 1_0's frequency-domain assignment field is ceil(log2(N_RB x (N_RB+1) / 2)) bits wide, so it depends on the bandwidth part it was sized against. A DCI 1_1's field set depends on which optional features are enabled. The specification therefore defines an alignment procedure that runs in steps and pads or truncates until the budget is met:

StepWhat it doesEffect on size count
Size 0_0/1_0 in the CSSSized against the initial DL BWP (N_RB of CORESET#0 or of the initial BWP), whatever the active BWP isFixes one size that never changes with BWP switching
Align 0_0 to 1_0If DCI 0_0 is shorter, zero-pad it; if longer, truncate the MSBs of its frequency-domain assignmentCollapses two formats into one size
Separate 0_1 and 1_1If DCI 0_1's size would equal the 0_0/1_0 size, append one padding bit. Same for DCI 1_1Deliberately prevents a size collision, because a collision here would make uplink and downlink grants indistinguishable
Check the budgetCount distinct sizes and distinct C-RNTI sizesIf four and three are respected, stop
Re-derive the USS 0_0/1_0 sizeIf the budget is exceeded, the UE-specific 0_0/1_0 sizes are re-derived from the initial DL BWP size with padding or truncation, so they coincide with the common-search-space sizesRemoves one size. This is why a UE that would need a fifth size gets a truncated or padded format instead of a configuration failure

Table 11. The size-alignment procedure, abridged. The last step is the one worth internalising: the specification's answer to too many sizes is to make a format lie about its bandwidth part, not to reject the configuration.

📘
Spec detail

The consequence of that last step is a real and slightly unnerving behaviour: a DCI 0_0 monitored in a UE-specific search space may have its frequency-domain assignment truncated, so it cannot address the full active bandwidth part even though the UE is using it. Truncation removes the most significant bits of the RIV, which restricts the set of (start, length) allocations expressible. This is legal, specified, and invisible -- and it is why a fallback uplink grant sometimes cannot express the allocation the scheduler wanted, in a cell where the non-fallback grant can.

🧮
Worked calculation

Given: 106-PRB BWP at 30 kHz, so the DCI 1_0 frequency-domain assignment is ceil(log2(106 x 107 / 2)) = ceil(log2(5671)) = 13 bits.

DCI 1_0 field budget:

identifier 1

frequency domain assignment 13

time domain assignment 4

VRB-to-PRB mapping 1

modulation and coding scheme 5

new data indicator 1

redundancy version 2

HARQ process number 4

downlink assignment index 2

TPC command for PUCCH 2

PUCCH resource indicator 3

PDSCH-to-HARQ feedback timing 3

---

payload A = 41 bits

+ 24-bit CRC = 65 bits to the polar encoder

DCI 0_0 over the same BWP totals 33 bits, so step 2 zero-pads it with 8 bits to reach 41. Those eight bits are transmitted, coded and decoded, and carry nothing. That is the price of collapsing two formats into one size, and it is cheaper than the alternative.

10. Overbooking, and the Search Space That Stops Being Monitored

A configuration can ask for more than the budget allows. The ASN.1 permits it, the gNB may send it, and the UE accepts it -- and then resolves the excess unilaterally, by not monitoring some of its search spaces. This is specified behaviour, not an error condition, and it is the single most important mechanism in this document TS 38.213 cl. 10.1.

10.1 The rule

  1. Allocate candidates and non-overlapping CCEs to every common search space set with an occasion in this slot. Common search space sets are never dropped, whatever they cost -- the UE will exceed neither limit on their account, because the network is required not to overbook common search spaces in the first place.
  2. Then consider the UE-specific search space sets in increasing order of searchSpaceId.
  3. Allocate each one in turn, provided that doing so keeps both the running candidate total within M_max,slot and the running non-overlapping-CCE total within C_max,slot.
  4. At the first UE-specific search space set that does not fit, stop. That set and every UE-specific set with a higher searchSpaceId is not monitored in this slot.

Read step 4 twice. It is not "drop candidates until it fits" and it is not "drop the candidates that do not fit". It is stop allocating, which abandons whole search space sets. A search space set that asks for twelve candidates when only three remain in the budget does not get three -- it gets zero, and so does everything above it.

Figure 5. The dropping procedure. The dependency on searchSpaceId ordering rather than on importance is the design's one real weakness: the identifier is usually assigned by a configuration template, and nothing warns you that identifier 7 has become the cut line.

10.2 A resolution, worked

🧮
Worked calculation

mu = 1: M_max,slot = 36, C_max,slot = 56. Slot 4, C-RNTI 0x4C11.

CORESET 1 = 16 CCEs (p = 1, A_p = 39829). CORESET 2 = 8 CCEs (p = 2, A_p = 39839).

Y(1, slot 4) = 30950. Y(2, slot 4) = 57168.

Configured search space sets with an occasion in slot 4:

id 1 COMMON type3, CORESET 1, symbol 0

AL2 n2 + AL4 n2 + AL8 n1 = 5 candidates

Y = 0 (common): AL2 {0-1, 8-9}, AL4 {0-3, 8-11}, AL8 {0-7}

union = CCE 0..11 = 12 CCEs

id 2 USS CORESET 1, symbol 0

AL1 n8 + AL2 n8 + AL4 n4 + AL8 n2 = 22 candidates

AL8 {0-7, 8-15} alone covers the CORESET = 16 CCEs

id 3 USS CORESET 2, symbol 0

AL1 n6 + AL2 n4 + AL4 n2 = 12 candidates

union = all 8 CCEs of CORESET 2 = 8 CCEs

id 4 USS CORESET 1, symbol 7

AL1 n4 + AL2 n2 + AL4 n2 = 8 candidates

union = 14 of the 16 CCEs = 14 CCEs

configured total: 5 + 22 + 12 + 8 = 47 candidates vs a limit of 36

Resolution:

common sets first: M = 5, C = 12 both OK

id 2: M = 5 + 22 = 27 <= 36; C = 16 (same bucket) both OK, keep

id 3: M = 27 + 12 = 39 > 36 DOES NOT FIT

-> stop. id 3 is not monitored.

id 4: higher searchSpaceId than 3 not monitored

Monitored in slot 4: 27 candidates, 16 non-overlapping CCEs.

Not monitored: searchSpaceId 3 and searchSpaceId 4.

Look at what was lost. searchSpaceId 3 was the only search space on CORESET 2 -- a different beam, a different part of the band -- so the UE has stopped monitoring that CORESET entirely. searchSpaceId 4 was the symbol-7 occasion, the whole reason the configuration existed: it was there to halve grant latency. Both are gone, and the configuration file still says they are configured.

10.3 Why this is the failure mode to memorise

Every other failure in this document leaves a trace somewhere. This one leaves nothing, on either side, and the reason is structural rather than an oversight:

Who might noticeWhat they would needWhy they do not
The UEA way to report I am not monitoring what you configuredThere is no such report. No RRC message, no MAC CE, no UE assistance information field, no failure cause. The dropping rules are UE behaviour, and correct behaviour is not reported
The gNB RRCValidation of the configuration it just sentVendors vary. Some check M_max,slot at configuration time; almost none check C_max,slot; and neither check is mandated. The RRCReconfigurationComplete that comes back says nothing about monitoring
The gNB schedulerKnowledge of which search spaces the UE actually monitorsIt has none. It computes candidates for all configured search spaces and transmits into them. Grants sent into a dropped search space are transmitted, consume CCEs, and are never received
The HARQ processA NACKA missed DCI produces neither an ACK nor a NACK -- it produces nothing, because the UE never knew a transmission was expected. See companion 05 HARQ

Table 12. Why an overbooked configuration is silent at every layer that could plausibly detect it. The only reliable detection is arithmetic performed off-line against the configuration.

⚠️
Common pitfall

The symptom is a UE that behaves as if it had a coverage problem in perfect radio conditions: grants intermittently unacknowledged, throughput below expectation, occasional RLC retransmissions, and eventually t310-driven radio link failure if the dropped search space was the only one carrying its scheduling. Every measurement the UE reports -- RSRP, RSRQ, SINR, CQI -- looks healthy, because the radio is healthy. If you are chasing a coverage complaint and the measurements disagree with the symptom, add up the candidates and the CCEs before you look at anything else.

📘
Spec detail

There is one asymmetry worth knowing. The dropping procedure is defined for the primary cell. On a secondary cell the network is required not to overbook -- so if it does, UE behaviour is not specified and differs between chipsets. An SCell configuration that exceeds the budget is therefore worse than a PCell one: at least the PCell case has a defined, reproducible outcome you can compute in advance.

11. Inside One Decode Attempt

One candidate, one DCI size, one attempt. Five steps, all of which the UE performs without knowing whether there is anything there.

  1. Collect the coded bits. L x 108 QPSK symbol pairs from the candidate's CCEs, demodulated using the channel estimate formed from the CORESET's DMRS. 108 bits per CCE: 6 REGs x 9 data resource elements x 2 bits, and PDCCH is always QPSK.
  2. Descramble. The PDCCH bit sequence is scrambled with a Gold sequence initialised from pdcch-DMRS-ScramblingID (or the physical cell identity if that IE is absent) and, in a UE-specific search space with pdcch-DMRS-ScramblingID configured, from the C-RNTI as well TS 38.211 cl. 7.3.2.3.
  3. Polar decode to A + 24 bits, where A is the DCI size being attempted. Successive-cancellation list decoding, with the CRC used inside the decoder to pick among the surviving paths.
  4. De-mask and check the CRC. XOR the RNTI into the last 16 of the 24 CRC bits and check. Repeat for each RNTI the UE owns in this search space -- C-RNTI, CS-RNTI, MCS-C-RNTI, and in a common search space SI-RNTI, P-RNTI, RA-RNTI, SFI-RNTI as applicable.
  5. Validate the payload. A CRC pass is necessary but not sufficient (section 12).

11.1 The CRC, and why it is 24 bits

PDCCH uses a 24-bit CRC, generated by the g_CRC24C polynomial, and it is attached to a payload that is typically 40 to 80 bits. So the CRC is a third to a half the size of the message it protects, which is an unusual ratio and entirely deliberate: it is not sized for error detection on a single block, it is sized for error detection across tens of thousands of speculative decodes per second (section 12).

Figure 6. The RNTI mask, bit by bit, for C-RNTI 0x4C11. Only the last 16 of the 24 CRC bits are masked; the first 8 are transmitted unmodified, which is what leaves a residual 8 bits of pure error detection independent of the addressing function.
TS 38.212 cl. 7.3 -- DCI CRC attachment with RNTI scrambling
Payload:   a_0, a_1, ... a_(A-1)              A = DCI size in bits
CRC:       p_0, p_1, ... p_23                 g_CRC24C over a_0..a_(A-1)

Transmitted sequence b_0 .. b_(A+23):

    b_k = a_k                                   for k = 0 .. A-1
    b_(A+j) = p_j                               for j = 0 .. 7
    b_(A+j) = p_j  XOR  x_rnti,(j-8)            for j = 8 .. 23

  where x_rnti,0 .. x_rnti,15 is the 16-bit RNTI, MSB first.

Worked, C-RNTI 0x4C11:
    0x4C11 = 0100 1100 0001 0001
    p_8  XOR 0    p_12 XOR 1    p_16 XOR 0    p_20 XOR 0
    p_9  XOR 1    p_13 XOR 1    p_17 XOR 0    p_21 XOR 0
    p_10 XOR 0    p_14 XOR 0    p_18 XOR 0    p_22 XOR 0
    p_11 XOR 0    p_15 XOR 0    p_19 XOR 1    p_23 XOR 1

  Six CRC bits are inverted for this RNTI; the other eighteen pass
  through. A UE de-masking with a different RNTI inverts a different
  subset and the CRC fails.

Listing 2. CRC attachment and RNTI scrambling. Note that the mask is a fixed XOR, not a permutation or an encryption -- there is no security property here at all, only addressing. Any UE can de-mask any DCI with any RNTI it cares to try.

11.2 Polar coding, and what the higher aggregation levels actually buy

The A + 24 bits go to a polar encoder with a mother code length N = 2^n, capped at 512 for downlink control, and are then rate-matched to E = 108 L bits TS 38.212 cl. 5.3.1. That cap has a consequence most treatments skip:

ALE = 108 LMother code NRate matchingWhat the step buys
110812820 bits shortenedBaseline
221625640 bits shortenedGenuine polar coding gain: a longer mother code with more frozen bits
443251280 bits shortenedGenuine polar coding gain, and the last step that gets any. N is now at its maximum
8864512352 bits repeatedRepetition, not additional coding gain. Energy per information bit doubles, which is worth about 3 dB, but the code itself is no stronger
1617285121216 bits repeatedMore repetition. Another ~3 dB of energy, still the same code

Table 13. Rate matching at each aggregation level. The qualitative break between AL4 and AL8 is real: below it you are buying code, above it you are buying power. Both help, but they help differently against fading and against interference.

📘
Spec detail

This is why the effective-code-rate curve in Figure 7 understates how good AL4 is and overstates AL16. Halving the code rate from 0.39 to 0.19 between AL2 and AL4 is a genuine coding gain of roughly 3 dB plus the energy gain. Halving it again from 0.097 to 0.049 between AL8 and AL16 is energy only. If your link budget says AL16 should work and it does not, the mother-code cap is a candidate explanation -- and so is the fact that an AL16 candidate consumes an entire 16-CCE CORESET, so it is competing against nothing except the possibility of not being scheduled at all.

12. False Alarms, and DCI That Passes CRC but Makes No Sense

A 24-bit CRC has a false-pass probability of about 2^-24 per attempt against random input. That is a small number. It is not small enough.

12.1 The arithmetic

🧮
Worked calculation

Given: mu = 1 (30 kHz), 2000 slots per second. A UE monitoring 20 candidates per slot at two DCI sizes = 40 decode attempts per slot.

attempts per second = 40 x 2000 = 80,000

P(false CRC pass) = 2^-24 = 5.96 x 10^-8

false alarms per second = 80,000 x 5.96e-8 = 4.8 x 10^-3

mean time between false alarms = 210 s, about 3.5 min

Per UE. In a cell with 200 UEs at that monitoring load:

cell-wide false alarms = about 1 per second

And the list decoder makes it worse. CRC-aided successive-cancellation list decoding with list size 8 evaluates up to 8 candidate paths and accepts the first that passes CRC, so the effective false-alarm rate is up to 8x the per-attempt figure:

mean time between false alarms, list 8 = about 26 s per UE

The list-size inflation is implementation-dependent -- decoders that verify the CRC only on the best surviving path do better -- so treat 8x as a bound rather than a value.

Twenty-six seconds per UE is not a rounding error. It means that in any loaded cell, several times a second, some UE somewhere decodes a DCI that was never transmitted, out of noise, with a valid CRC and its own RNTI. The design has to survive that, and it does -- but only because of the validation layer in section 12.2, which is why that layer is part of the specification and not left to implementations.

12.2 What the UE does with a DCI that passes CRC

It checks whether the payload makes sense, and discards it if not. Some of these checks are explicit in the specification, some follow from field ranges, and all of them are performed before the DCI is acted on:

CheckWhat fails itSpecified where
Reserved and invalid field valuesA DCI 1_0 with SI-RNTI has fields that must be all-ones or all-zeros; a TDRA row index beyond the configured pdsch-TimeDomainAllocationList; an MCS index in the reserved rangeField descriptions in TS 38.212 cl. 7.3.1 and the corresponding procedure text in TS 38.214
HARQ process identityA HARQ process number at or above nrofHARQ-ProcessesForPDSCH -- the UE has no such processTS 38.214 cl. 5.1; see companion 05 HARQ
Frequency-domain assignment out of rangeAn RIV that decodes to PRBs beyond the active bandwidth partTS 38.214 cl. 5.1.2.2
Bandwidth part indicatorA BWP index that is not configuredTS 38.213 cl. 12
SPS / configured-grant validationAn activation or release DCI whose specific fields are not the required all-zero patterns. A DCI failing this validation is treated as if the CRC had failedTS 38.213 cl. 10.2 -- the one place the specification says this explicitly
Timing consistencyA PDSCH-to-HARQ_feedback timing value pointing at a slot the UE cannot transmit in, or a K0 that lands the PDSCH before the DCITS 38.213 cl. 9.2 and TS 38.214 cl. 5.3

Table 14. The validation layer. Only the SPS row uses the phrase "as if the CRC had failed"; the others are ordinary field-range constraints, but the practical effect is the same -- the DCI is dropped and nothing is reported.

12.3 When a false alarm is not caught

The uncomfortable case is a false-alarm DCI whose random payload happens to be internally consistent. Every field is in range, the HARQ process exists, the allocation fits the BWP. Nothing rejects it, and the UE acts on it. What happens next depends on whether it decoded as a downlink assignment or an uplink grant:

The phantom DCI wasWhat the UE doesWhat the gNB sees
A downlink assignment (DCI 1_0 / 1_1)Receives noise on the indicated PDSCH resources, fails the transport block CRC, sends a NACK on the indicated PUCCH resourceA HARQ-ACK bit on a PUCCH resource it did not allocate, for a HARQ process it did not transmit. Most schedulers log this as an unexpected or spurious UCI and discard it
An uplink grant (DCI 0_0 / 0_1)Transmits a PUSCH on the indicated resources -- real energy, real DMRS, at a real power levelInterference on PRBs it allocated to another UE, in a slot it may have configured as downlink. This is the more damaging case, and it shows up as unexplained uplink interference or a decode failure for the UE that legitimately owned those PRBs
An SPS activationCaught by the explicit validation in TS 38.213 cl. 10.2, with overwhelming probabilityNothing. This is precisely what the validation rules exist to prevent

Table 15. Uncaught false alarms. The uplink case is why PDCCH false-alarm rate is a real design constraint rather than an academic one: a phantom grant becomes interference in someone else's allocation.

🔍
What you see in logs

Spurious uplink transmissions with no corresponding grant are worth a specific look when you see unexplained uplink interference on a lightly loaded cell. Check whether the timing lines up with a PDCCH monitoring occasion plus the K2 of a plausible time-domain allocation row. If it does, and the UE identity resolves to a UE with a heavy monitoring configuration, a false-alarm grant is a credible explanation -- and the mitigation is fewer candidates or fewer DCI sizes, not more power.

13. Aggregation Level Selection, From the gNB Side

Everything so far has been about what the UE searches. The other half of the negotiation is the gNB deciding which candidate to use, and that decision is link adaptation for a channel with no HARQ, no modulation adaptation and no direct feedback.

Figure 7. Effective code rate at each aggregation level for three DCI payloads. A DCI 1_1 with every optional field enabled is unschedulable at AL1 -- R = 0.944 -- so enabling optional DCI fields silently removes the cheapest aggregation level from the scheduler's menu.

13.1 Why PDCCH must be conservatively coded

PDCCH has no HARQ. There is no retransmission, no soft combining, no second chance -- a PDCCH that is not decoded is simply lost, and the grant it carried disappears with it. Compare that to PDSCH, which is routinely operated at 10% first-transmission BLER because HARQ recovers the residue at low cost (companion 05 HARQ). PDCCH cannot afford that, and is normally targeted at 1% BLER or better.

Worse, a lost PDCCH is asymmetrically expensive. If the lost DCI was a downlink assignment, the UE sends no HARQ feedback at all -- not a NACK, nothing -- so the gNB must wait for a timeout to infer the loss, and cannot distinguish a lost PDCCH from a lost PUCCH. If it was an uplink grant, the allocated PUSCH resources go unused and the gNB sees an empty slot. Either way the recovery latency is much longer than a HARQ round-trip, which is why schedulers protect PDCCH out of proportion to its payload.

13.2 The coding rate at each aggregation level, worked

🧮
Worked calculation

Usable coded bits at aggregation level L, QPSK:

E(L) = L x 6 REGs x 9 data REs x 2 bits/RE = 108 L

DCI 1_0, A = 41, K = 41 + 24 = 65:

AL1: R = 65 / 108 = 0.602 only at high SINR

AL2: R = 65 / 216 = 0.301

AL4: R = 65 / 432 = 0.150 comfortable cell-edge margin

AL8: R = 65 / 864 = 0.075

DCI 1_1, A = 60, K = 84:

AL1: R = 84 / 108 = 0.778 do not schedule here

AL2: R = 84 / 216 = 0.389

AL4: R = 84 / 432 = 0.194

DCI 1_1 with every optional field, A = 78, K = 102:

AL1: R = 102 / 108 = 0.944 unusable at any SINR

AL2: R = 102 / 216 = 0.472

AL4: R = 102 / 432 = 0.236

The cost of the optional fields, at constant aggregation level:

10 x log10(0.236 / 0.150) = 1.96 dB of margin given up at AL4

relative to the fallback DCI 1_0 -- for eighteen bits.

That 1.96 dB is the number to keep in mind when someone proposes enabling tci-PresentInDCI, code-block-group retransmission, a second bandwidth part, or an SRS request field. Each addition is a handful of bits and each lands on a channel already running at a code rate between 0.15 and 0.8. The aggregation-level ladder shifts up by a fraction of a step for every UE in the cell, and CORESET occupancy rises with it.

13.3 What actually drives the decision

InputWhere it comes fromHow it is usedSpecified?
PDCCH SINR estimateDerived from the CSI report, or reciprocated from the SRS-based uplink estimate in TDDThe primary driver: map estimated SINR to the lowest aggregation level meeting the PDCCH BLER targetNo -- entirely implementation
DTX inferenceA HARQ-ACK that never arrived where one was expectedOuter-loop correction: raise the aggregation level for this UE after consecutive misses, decay it back over timeNo
Free CCEs at this occasionThe scheduler's own CCE occupancy mapHard constraint. A UE needing AL8 in a CORESET with 6 free CCEs is not scheduled this occasionImplied by the CORESET size
Candidate availabilitynrofCandidates at that level, and the hash output for this slotHard constraint. The level must have a non-zero candidate count and an unoccupied position (section 6)Yes -- TS 38.213 cl. 10.1
Message importanceScheduler policyMany implementations force a high aggregation level for an RRCReconfiguration or a handover command regardless of the channel estimateNo
DCI payload sizeThe configured formats and optional fieldsSets the code rate at each level, per section 13.2Yes -- TS 38.212 cl. 7.3.1

Table 16. Aggregation-level selection inputs. Only two rows are specified; the rest is vendor behaviour and should be described as such when characterising a scheduler. See companion 34 Link Adaptation for the outer-loop machinery this shares with MCS selection.

🔍
What you see in logs

The aggregation-level histogram is the most informative PDCCH statistic that is routinely collected, and it reads directly.

A healthy loaded FR1 macro cell is dominated by AL2 and AL4 with a thin AL8 tail.

Almost all AL1 means either an unusually well-covered cell or a scheduler under-protecting PDCCH -- cross-check PDCCH BLER.

Almost all AL8 and AL16 means the CORESET is being spent on a handful of UEs per occasion, and PDCCH blocking will appear long before PRB exhaustion.

A histogram that shifts upward after a software or configuration change with no radio change usually means the DCI got bigger.

14. Cross-Carrier Scheduling and the Per-UE Budget

The per-slot limits in section 7 are per serving cell, and a UE with eight configured downlink cells does not get eight times the budget. It gets what it said it could do, apportioned.

14.1 The capability, and the scaling

The UE reports pdcch-BlindDetectionCA in CA-ParametersNR, an integer in the range 4 to 16 TS 38.306. Read it as the number of single-cell budgets' worth of blind decoding I can perform per slot in total. Then:

ConditionPer-cell limitsConsequence
Configured downlink cells <= pdcch-BlindDetectionCAThe full single-cell M_max,slot and C_max,slot apply to each cell independentlyEach cell's configuration can be validated on its own. The common and comfortable case
Configured downlink cells > pdcch-BlindDetectionCAThe per-cell limits are scaled down in proportion to the ratio of the reported capability to the number of configured downlink cells TS 38.213 cl. 10.1Every cell's budget shrinks, including the PCell's, and the shrinkage happens at SCell addition -- not at activation

Table 17. The two regimes. The exact floor and ceiling conventions and the per-numerology split for mixed-numerology carrier aggregation are in TS 38.213 clause 10.1; the shape is a proportional scale-down.

🧮
Worked calculation

Given: a UE reporting pdcch-BlindDetectionCA = 8, configured with 12 downlink cells, all at 30 kHz.

single-cell limits at mu = 1: M = 36, C = 56

ratio = 8 / 12 = 0.667

per-cell M = floor(0.667 x 36) = 24

per-cell C = floor(0.667 x 56) = 37

The PCell configuration in section 8.3 needed 35 candidates. It fits 36. It does not fit 24. Nothing about the PCell changed -- eight secondary cells were added, and the PCell's own search spaces started being dropped as a result.

⚠️
Common pitfall

This is the CA failure that costs the most debugging time, because the cause and the effect are on different carriers. The trigger is an RRCReconfiguration adding SCells; the symptom is degraded PCell scheduling. The two are separated by whatever interval elapses before the PCell's dropped search space is actually needed, which may be minutes. If PCell behaviour degrades after an SCell addition, recompute the PCell candidate count against the scaled limit before looking at anything on the SCell. See companion 29 Carrier Aggregation.

14.2 Which cell's budget a cross-carrier candidate consumes

With cross-carrier scheduling, the PDCCH for a scheduled SCell is transmitted in a CORESET on the scheduling cell. The candidates are monitored on the scheduling cell, so they consume the scheduling cell's budget, at the scheduling cell's numerology. Three practical consequences:

  • A PCell scheduling four SCells carries five cells' worth of candidates in its own CORESETs against its own M_max,slot. The SCells' budgets go unused. This is the direct mechanism by which carrier aggregation starves PDCCH.
  • n_CI separates the candidate sets so they do not systematically collide (section 4.4), but separation does not create budget. Five distinct rotations of the same CORESET still cost five times the candidates.
  • When the scheduling and scheduled cells have different numerologies, the limits that apply are those of the numerology of the cell whose budget is being consumed, and TS 38.213 clause 10.1 defines how mixed numerologies are combined. Mixed-numerology CA is where the capability signalling gets its own extension IEs (section 18).
ConfigurationPCell candidates per slotFits M_max = 36?
No CA, one search space set at 16 candidates16Yes, comfortably
No CA, the section 8.3 configuration35Yes, by one
Self-scheduled PCell + 1 cross-carrier SCell, same config each70No. Two cells' candidates in the PCell's budget
Self-scheduled PCell + 3 cross-carrier SCells140No, by a factor of four. The configuration must be thinned per scheduled cell

Table 18. Why cross-carrier scheduling forces sparse per-cell search space configurations. A configuration that is sensible for one cell is almost never sensible replicated across four scheduled cells in one scheduling cell's budget.

15. Rel-16 Span-Based Monitoring and the Per-Span Budget

Rel-15 assumed the UE monitors at most one occasion per slot, near the slot boundary, which puts the worst-case wait for a grant at one slot. For URLLC that is most of the latency budget. Rel-16's answer is to monitor several times per slot and to redefine the budgets per span rather than per slot.

15.1 What a span is, and the (X, Y) pairs

A span is a window of consecutive OFDM symbols containing all of a UE's monitoring occasions in that window. The capability is a pair: X is the minimum separation between the first symbols of consecutive spans, Y is the maximum span length. The UE reports which pairs it supports and the network must configure monitoringSymbolsWithinSlot so that every occasion falls inside a supported pattern.

Figure 8. The three span patterns inside a 14-symbol slot, with the per-span candidate budget at 30 kHz. Note that (2, 2) offers seven times the monitoring opportunities at a third of the budget each -- more total budget than Rel-15, but far less per occasion.
(X, Y)Spans per slotM per span, mu = 0 / mu = 1C per spanWhere it is used
(7, 3)244 / 3656The mildest span capability: one monitoring opportunity per half slot. Widely supported
(4, 3)328 / 2436Mid-range URLLC. At 30 kHz a span every 4 symbols is about 143 us
(2, 2)714 / 1218The most aggressive pattern, and the practical floor for grant latency. Implies materially more PDCCH processing hardware and is not universal
Rel-15144 / 3656 / 56One occasion per slot. Still the baseline every UE must support

Table 19. Per-span limits from TS 38.213 Tables 10.1-2A and 10.1-3A. The (7, 3) row reproduces the per-slot values, so a span-capable UE gets strictly more total budget than a Rel-15 one -- which is the whole reason the capability is signalled rather than assumed.

15.2 Why URLLC needs it, in microseconds

🧮
Worked calculation

At 30 kHz one OFDM symbol is about 35.7 us and one slot is 500 us.

Rel-15, one occasion per slot:

average wait for the next occasion = 0.5 x 500 = 250 us

worst case = 500 us

Rel-16 (2, 2), seven occasions per slot, every 2 symbols = 71.4 us:

average wait = 0.5 x 71.4 = 36 us

worst case = 71 us

saving in worst-case grant wait = 429 us

Against a 1 ms end-to-end URLLC budget that is 43% of the budget recovered before any data is transmitted.

15.3 The budget consequence, which is the catch

More occasions do not mean proportionally more candidates. Compare the totals per slot at 30 kHz:

🧮
Worked calculation

Rel-15: 1 span x 36 candidates = 36 candidates per slot

(7, 3): 2 spans x 36 = 72 candidates per slot

(4, 3): 3 spans x 24 = 72 candidates per slot

(2, 2): 7 spans x 12 = 84 candidates per slot

Rel-15: 1 x 56 CCEs = 56 CCEs per slot

(2, 2): 7 x 18 = 126 CCEs per slot

So (2, 2) buys 2.3x the candidates and 2.25x the CCEs of Rel-15 in total -- but only 12 candidates and 18 CCEs in any one span. An 18-CCE per-span CCE limit will not accommodate a 24-CCE CORESET at all if the candidate set spans it.

⚠️
Common pitfall

The per-span CCE limit is the constraint that catches people, because it interacts with CORESET size rather than with candidate counts. A 48-PRB two-symbol CORESET is 16 CCEs and fits inside an 18-CCE per-span budget with room for nothing else. A 96-PRB two-symbol CORESET is 32 CCEs and cannot be fully monitored in a (2, 2) span at all -- the candidate set must be configured so that its non-overlapping CCE union stays under 18, which in practice means no AL8 or AL16 candidates. Wide CORESETs and aggressive span monitoring are close to mutually exclusive.

15.4 Configuring spans against a UE that did not report them

⚠️
Common pitfall

Configuring span-based monitoring for a UE that did not report the capability is a real and quiet failure. The UE applies the search space configuration it was given, because there is no rule telling it to reject it -- but its budget is the Rel-15 per-slot one, so all the occasions in the slot compete for 36 candidates and 56 CCEs. The overbooking rules then drop the highest-numbered UE-specific search spaces, which are typically exactly the ones added to create the extra occasions. The result is a UE that monitors the first occasion of each slot and nothing else: Rel-15 latency from a Rel-16 configuration, with no error anywhere. Always check pdcch-MonitoringAnyOccasionsWithSpanGap in the capability report before believing a sub-slot configuration does anything. See companion 26 UE Capability.

15.5 Rel-17: the opposite problem

In FR2-2 with 480 or 960 kHz subcarrier spacing a slot is 31 or 15.6 us long, and monitoring every slot would demand absurd processing rates for no benefit. Rel-17 therefore allows the candidate and CCE limits to be defined over a group of slots, so the UE may concentrate its decode budget in some slots of the group and skip others. The configuration mechanism is unchanged; what changes is the interval the overbooking rules are applied over.

Rel-17 also added PDCCH skipping and search space set group switching: a DCI can tell the UE to stop monitoring PDCCH for a configured duration, or to switch between a dense and a sparse group of search spaces, without an RRC message and without leaving DRX Active Time. Both appear in logs as a UE that stops monitoring with no DRX transition and no configuration change, which is easy to misread as a lost UE -- and easy to confuse with the overbooking case in section 10, from which it differs in being deliberate, commanded, and reversible.

16. Parameter and Capability Reference

16.1 Configuration parameters that drive blind decoding

ASN.1 name / symbolRange / valuesTypicalEffect on the candidate set or the budget
nrofCandidates.aggregationLevelLn0, n1, n2, n3, n4, n5, n6, n8 (no n7)AL1 n6, AL2 n6, AL4 n2, AL8 n2, AL16 n0M_p,L in the mapping formula, and the direct contribution to M_max,slot. Values above floor(N_CCE,p / L) alias (section 5.4)
searchSpaceId0 .. 39 (maxNrofSearchSpaces = 40)1 .. 10The drop order under overbooking. Note the range is 40 even though only 10 search spaces may be configured per BWP, so the identifiers need not be contiguous
controlResourceSetId0 .. 11 (maxNrofControlResourceSets = 12)0 for CORESET#0, 1 .. 3 dedicatedp in the mapping, which selects A_p via p mod 3 and therefore the whole hash sequence
searchSpaceTypecommon | ue-SpecificBoth, in one BWPcommon forces Y_p,n = 0 and exempts the set from dropping
dci-Formatsformats0-0-And-1-0 | formats0-1-And-1-1 (+ Rel-16 ...Ext)formats0-1-And-1-1How many DCI sizes this search space set contributes, and therefore the decode-attempt multiplier
monitoringSymbolsWithinSlotBIT STRING (SIZE (14))10000000000000Occasions per slot. Every additional set bit duplicates the CORESET's CCE cost in a new counting bucket (section 8.2)
cif-InSchedulingCell0 .. 7absent, or 1 .. 3n_CI in the mapping. Non-zero rotates the scheduled cell's candidates away from the scheduling cell's
pdcch-DMRS-ScramblingID0 .. 65535= physCellIdDescrambling initialisation. A mismatch fails every CRC in that CORESET with no other symptom
monitoringCapabilityConfig-r16r15monitoringcapability | r16monitoringcapabilityr15monitoringcapabilitySelects per-slot or per-span budget accounting. Must match what the UE reported (section 15.4)

Table 20. SearchSpace and related fields, read as inputs to the arithmetic rather than as configuration. The companion 30 CORESET and Search Space document covers the same IEs from the configuration side.

16.2 Fixed constants

SymbolValueMeaning
D65537Modulus of the hashing recursion. Prime, 2^16 + 1
A_p39827 / 39829 / 39839Multiplier for p mod 3 = 0 / 1 / 2
Y_p,-1n_RNTISeed. The C-RNTI, which must be non-zero
Coded bits per CCE1086 REGs x 9 data REs x 2 bits, QPSK
DCI CRC length24 bitsg_CRC24C; last 16 bits RNTI-masked
Polar mother code capN = 512Downlink control; n_max = 9
Aggregation levels1, 2, 4, 8, 16Five, and only five

Table 21. Constants worth having memorised, because every hand computation in this document uses at least three of them.

16.3 UE capabilities

Capability IEWhereRangeWhat it gates
pdcch-BlindDetectionCACA-ParametersNRINTEGER (4..16)Total blind-detection budget across configured downlink cells. Below the configured cell count, per-cell limits are scaled down (section 14)
pdcch-BlindDetectionCA-Mixed-r16CA-ParametersNR-v16xytwo INTEGERs (1..15)Separate budgets for the two numerology groups in mixed-numerology carrier aggregation
pdcch-MonitoringAnyOccasionsPhy-ParametersFRX-DiffwithoutDCI-Gap | withDCI-GapWhether the UE can monitor occasions anywhere in the slot at all, and whether it needs a gap after a DCI
pdcch-MonitoringAnyOccasionsWithSpanGapPhy-ParametersFRX-Diffper-SCS set1 | set2 | set3The supported (X, Y) span pairs: set1 = (7,3), set2 = (4,3), set3 = (2,2). The gate on Rel-16 span monitoring
multiDCI-MultiTRP / PDCCH repetition capabilitiesMIMO-ParametersPerBand and Rel-17 additionssupported / absentWhether linked candidates across two search space sets may be configured, and how they are counted

Table 22. Capability IEs that bound blind decoding. All of them are permissive -- absence means the baseline, never an error -- which is why configuring beyond a capability produces silence rather than rejection. See companion 26 UE Capability.

17. Failure Modes, and What Each Looks Like in a Log

Nine ways blind decoding goes wrong. Seven of them are silent on both sides, which is why the last column is mostly about arithmetic you perform yourself rather than a line you search for.

What failsWho detects itWhat the UE doesLog signature and how to confirm
Overbooking drops a search spaceNobody. The UE is behaving correctlyMonitors the common search spaces plus UE-specific sets in increasing searchSpaceId order until the budget runs out, then stopsNo signature at all. Confirm by summing candidates and non-overlapping CCEs from the RRCReconfiguration against the numerology's limits (section 8.3). Symptom: intermittent unacknowledged grants with healthy CQI and RSRP
DCI size budget exceededThe UE, silently, by applying the alignment procedureRe-derives the UE-specific 0_0/1_0 sizes from the initial DL BWP, padding or truncating the frequency-domain assignmentA fallback grant that cannot address the whole active BWP. Symptom: the non-fallback grant works and the fallback grant produces a misallocated PUSCH. Confirm by counting distinct DCI sizes across all configured search spaces
Hash collision between two UEsThe gNB scheduler, as a placement failureNothing -- it never knew a grant was intendedScheduling latency rising with cell load while PDCCH BLER stays flat (section 6.3). Look for a PDCCH blocking or CCE allocation failure counter in the scheduler statistics
A candidate would extend past the end of the CORESETNobody -- the formula cannot produce thisNothing. The outer mod floor(N_CCE,p / L) guarantees the candidate fitsIf you compute a candidate that overruns, your arithmetic is wrong, most often by using mod N_CCE,p instead of mod floor(N_CCE,p / L). This is a debugging tell, not a network fault
nrofCandidates is n0 at the aggregation level the scheduler wantsThe gNB scheduler, if it checks; many do notNever looks at that aggregation level in that search space setThe gNB transmits at an aggregation level with no candidate, or silently downgrades. Symptom: cell-edge UEs unreachable while cell-centre UEs are fine, with aggregationLevel8 or aggregationLevel16 set to n0
C_max,slot exceeded while M_max,slot passesNobodySame dropping procedure as overbooking, triggered by the CCE total instead of the candidate totalIdentical symptom to plain overbooking and a completely different fix. Count CCE buckets per (CORESET, first symbol) pair -- see section 8.4 Case B. Reducing nrofCandidates will not help
Cross-carrier scaling shrinks the per-cell budgetNobodyApplies the scaled limits and drops PCell search spaces accordinglyPCell degradation immediately following an SCell-addition RRCReconfiguration. Confirm from pdcch-BlindDetectionCA in the capability report against the configured downlink cell count (section 14.1)
A false-alarm DCI is acted onThe gNB, indirectly and after the factActs on it: sends a NACK on an unallocated PUCCH resource, or transmits a PUSCH nobody grantedUnexpected UCI on a PUCCH resource that was not allocated; or uplink interference correlated with a monitoring occasion plus a plausible K2. Rate scales with candidates x DCI sizes x slots (section 12.1)
PDCCH coded too aggressively when high aggregation levels are shortThe gNB, as PDCCH DTX inferenceFails to decode. No feedback of any kindPDCCH BLER above target concentrated in low-SINR UEs, plus an aggregation-level histogram with no AL8 tail. Usually a CORESET too small to hold AL8 candidates for more than one UE per occasion

Table 23. Failure modes. Note the pattern: the fourth column is an instruction to compute something in seven of nine rows, because there is nothing to observe. Blind decoding is the part of the air interface least amenable to log-driven diagnosis and most amenable to arithmetic.

💡
Key point

Two of these are distinguishable only by arithmetic and they have opposite fixes. M_max,slot exceeded is too many candidates, fixed by lowering nrofCandidates. C_max,slot exceeded is too much CORESET monitored, fixed by removing an occasion or a CORESET -- lowering nrofCandidates may not reduce the CCE union at all, because a single AL8 candidate can cover half a CORESET on its own. Always compute both totals before changing anything.

18. ASN.1 Structures

Abridged from TS 38.331 and TS 38.306, with ... marking omitted fields. Everything shown is real; the omissions are fields that do not affect the candidate set or the budgets.

PDCCH-Config ::= SEQUENCE {
    controlResourceSetToAddModList   SEQUENCE (SIZE (1..3)) OF
                                       ControlResourceSet    OPTIONAL,
    controlResourceSetToReleaseList  SEQUENCE (SIZE (1..3)) OF
                                       ControlResourceSetId  OPTIONAL,
    searchSpacesToAddModList         SEQUENCE (SIZE (1..10)) OF
                                       SearchSpace           OPTIONAL,
    searchSpacesToReleaseList        SEQUENCE (SIZE (1..10)) OF
                                       SearchSpaceId         OPTIONAL,
    downlinkPreemption               SetupRelease {
                                       DownlinkPreemption }  OPTIONAL,
    tpc-PUSCH                        SetupRelease { ... }    OPTIONAL,
    tpc-PUCCH                        SetupRelease { ... }    OPTIONAL,
    tpc-SRS                          SetupRelease { ... }    OPTIONAL,
    ...,
    [[ controlResourceSetToAddModList2-r16    ...            OPTIONAL,
       searchSpaceSwitchTimer-r16    INTEGER (1..20)         OPTIONAL
    ]]
}

-- ten search spaces per BWP, three dedicated CORESETs per BWP.
-- downlinkPreemption brings DCI 2_1 and INT-RNTI, which is a fourth
-- DCI size; check the four-size budget before enabling it.

Listing 3. PDCCH-Config. The SIZE (1..10) on the search space list is the only limit the ASN.1 imposes on monitoring load, and ten search spaces can easily ask for four times the per-slot budget.

SearchSpace ::= SEQUENCE {
    searchSpaceId                       SearchSpaceId,
    controlResourceSetId                ControlResourceSetId  OPTIONAL,
    monitoringSlotPeriodicityAndOffset  CHOICE {
        sl1        NULL,
        sl2        INTEGER (0..1),
        sl4        INTEGER (0..3),
        ...  sl2560 INTEGER (0..2559)   }                     OPTIONAL,
    duration                            INTEGER (2..2559)     OPTIONAL,
    monitoringSymbolsWithinSlot         BIT STRING (SIZE (14))
                                                              OPTIONAL,
    nrofCandidates                      SEQUENCE {
        aggregationLevel1   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
        aggregationLevel2   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
        aggregationLevel4   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
        aggregationLevel8   ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8},
        aggregationLevel16  ENUMERATED {n0,n1,n2,n3,n4,n5,n6,n8}
    }                                                         OPTIONAL,
    searchSpaceType                     CHOICE {
        common      SEQUENCE {
            dci-Format0-0-AndFormat1-0  SEQUENCE { ... }      OPTIONAL,
            dci-Format2-0               SEQUENCE {
                nrofCandidates-SFI      SEQUENCE {
                    aggregationLevel1   ENUMERATED {n1,n2}    OPTIONAL,
                    ...                                            }
            }                                                 OPTIONAL,
            dci-Format2-1               SEQUENCE { ... }      OPTIONAL,
            ...  dci-Format2-3          SEQUENCE { ... }      OPTIONAL
        },
        ue-Specific SEQUENCE {
            dci-Formats  ENUMERATED {formats0-0-And-1-0,
                                     formats0-1-And-1-1},
            ...,
            [[ dci-FormatsExt-r16  ENUMERATED {
                   formats0-2-And-1-2,
                   formats0-1-And-1-1And-0-2-And-1-2 }        OPTIONAL
            ]]
        }
    }                                                         OPTIONAL,
    ...,
    [[ searchSpaceGroupIdList-r16  SEQUENCE (SIZE(1..2)) OF
                                     INTEGER (0..1)           OPTIONAL
    ]]
}

SearchSpaceId ::= INTEGER (0..maxNrofSearchSpaces-1)   -- 0..39
ControlResourceSetId ::= INTEGER (0..maxNrofControlResourceSets-1)
                                                       -- 0..11

Listing 4. SearchSpace, abridged. Three things to note: nrofCandidates has no n7; SearchSpaceId ranges to 39 even though only ten search spaces fit in a BWP, so the drop order in section 10 follows the identifier and not the list position; and dci-FormatsExt-r16 adds formats 0_2 and 1_2, which participate in the same four-size budget.

-- Blind detection capability, TS 38.331 / TS 38.306

CA-ParametersNR ::= SEQUENCE {
    ...
    pdcch-BlindDetectionCA           INTEGER (4..16)         OPTIONAL,
    ...,
    [[ pdcch-BlindDetectionCA-Mixed-r16 SEQUENCE {
           pdcch-BlindDetectionCA1-r16  INTEGER (1..15),
           pdcch-BlindDetectionCA2-r16  INTEGER (1..15)
       }                                                     OPTIONAL
    ]]
}

Phy-ParametersFRX-Diff ::= SEQUENCE {
    ...
    pdcch-MonitoringAnyOccasions  ENUMERATED {
                                    withoutDCI-Gap,
                                    withDCI-Gap }            OPTIONAL,
    pdcch-MonitoringAnyOccasionsWithSpanGap SEQUENCE {
        scs-15kHz    ENUMERATED {set1, set2, set3}            OPTIONAL,
        scs-30kHz    ENUMERATED {set1, set2, set3}            OPTIONAL,
        scs-60kHz    ENUMERATED {set1, set2, set3}            OPTIONAL,
        scs-120kHz   ENUMERATED {set1, set2, set3}            OPTIONAL
    }                                                         OPTIONAL,
    ...
}
     -- set1 = (X,Y) = (7,3),  set2 = (4,3),  set3 = (2,2)

ServingCellConfig ::= SEQUENCE {
    ...,
    [[ monitoringCapabilityConfig-r16 ENUMERATED {
           r15monitoringcapability,
           r16monitoringcapability }                          OPTIONAL
    ]]
}

Listing 5. The capability and accounting-mode IEs. monitoringCapabilityConfig-r16 is the switch between per-slot and per-span budget accounting, and it is configured by the network -- so it can be set to r16monitoringcapability for a UE that never reported span support (section 15.4).

19. Worked Arithmetic

The calculations that matter are distributed through the document, next to the mechanism each one explains. This section indexes them and then runs one end-to-end configuration review of the kind you would actually perform before signing off a PDCCH-Config.

CalculationWhereThe answer, for reference
The hashing recursion, four slotsSection 5.1Y(1,n) = 25259, 47761, 61444, 35959 for C-RNTI 0x4C11 in CORESET 1
Candidate CCE positions, AL1 to AL8Sections 5.2, 5.316 candidates covering 42 CCE-positions across 16 physical CCEs; AL8 does not move between slots
Collision overlap between two UEsSection 6.2Four of six AL2 positions shared, with the membership changing every slot
Blind-decode count against both budgetsSection 8.335 candidates against 36; 27 non-overlapping CCEs against 56
A configuration that fails only C_maxSection 8.4 Case B12 candidates, 96 CCEs -- passes M by a wide margin, fails C
DCI 1_0 size for a 106-PRB BWPSection 9.241-bit payload, 65 bits to the encoder, DCI 0_0 zero-padded by 8
Overbooking resolutionSection 10.2searchSpaceId 3 and 4 are not monitored; 27 candidates survive
PDCCH false-alarm rateSection 12.1One per 210 s per UE, or about one per 26 s with a list-8 decoder
Coding rate at each aggregation levelSection 13.21.96 dB of margin given up at AL4 for eighteen optional DCI bits
Cross-carrier budget scalingSection 14.1pdcch-BlindDetectionCA 8 with 12 cells: per-cell M = 24, C = 37
Span monitoring latency and budgetSections 15.2, 15.3429 us of worst-case grant wait recovered; 12 candidates and 18 CCEs per span

Table 24. Index of the worked arithmetic. Any of these can be recomputed from the configuration alone -- none of them requires a capture, which is the point.

19.1 An end-to-end configuration review

A proposed PDCCH-Config for a 30 kHz FR1 cell, to be reviewed before deployment. Four search spaces, two CORESETs, no carrier aggregation yet. The question is whether it does what it says.

🧮
Worked calculation

Step 1 -- CORESET capacity.

CORESET 1: 48 PRB x 2 symbols = 96 REGs = 16 CCEs

CORESET 2: 24 PRB x 2 symbols = 48 REGs = 8 CCEs

Step 2 -- candidate counts per occasion.

SS 1 CSS type3, CORESET 1, sym 0: AL2 n2 + AL4 n1 = 3

SS 2 USS, CORESET 1, sym 0: AL1 n6+AL2 n6+AL4 n2+AL8 n2 = 16

SS 5 USS, CORESET 2, sym 0: AL1 n4+AL2 n4+AL4 n2 = 10

SS 9 USS, CORESET 1, sym 0 and sym 7: (AL1 n2+AL2 n2) x 2 = 8

M_slot = 37

Limit at mu = 1: 36. FAILS by one candidate.

Step 3 -- resolve the overbooking.

CSS first: SS 1 -> M = 3

SS 2 (id 2): 3 + 16 = 19 <= 36 keep

SS 5 (id 5): 19 + 10 = 29 <= 36 keep

SS 9 (id 9): 29 + 8 = 37 > 36 dropped

-> the sub-slot occasion at symbol 7 is never monitored.

Step 4 -- the CCE count, in case it also fails.

(CORESET 1, sym 0): SS 1 + SS 2. SS 2's two AL8 candidates cover the

whole CORESET -> 16

(CORESET 2, sym 0): SS 5's AL4 candidates cover 8 CCEs -> 8

(CORESET 1, sym 7): dropped with SS 9 -> 0

C_slot = 24 <= 56

The CCE budget is not the problem. Only M binds.

Step 5 -- DCI sizes.

SS 1 common, dci-Format0-0-AndFormat1-0 -> size A (41 bits)

SS 2, SS 5, SS 9 formats0-1-And-1-1 -> sizes B, C

Three sizes, all C-RNTI-monitored: 3 <= 3 OK, at the limit.

Enabling downlinkPreemption would add DCI 2_1 as a fourth size --

legal, since 2_1 uses INT-RNTI, but it is the last one available.

Step 6 -- high-aggregation-level sanity.

CORESET 1: floor(16/8) = 2 positions at AL8, and aggregationLevel8

is n2. No aliasing. Good.

CORESET 2: floor(8/4) = 2 positions at AL4, aggregationLevel4 n2.

No aliasing, but also no AL8 at all -- an 8-CCE CORESET holds exactly

one AL8 candidate, and none is configured. Cell-edge UEs cannot be

served on CORESET 2.

Verdict. The configuration is one candidate over budget, and the penalty falls entirely on searchSpaceId 9 -- the one search space whose purpose was latency. Removing one AL1 candidate from SS 2 brings the total to 36 and recovers the whole of SS 9. That is the entire fix, and nothing in any log would have told you.

💡
Key point

Two habits from that review are worth adopting permanently. First, renumber before you tune: put the search spaces you care most about at the lowest searchSpaceId values, so that if the budget is ever exceeded -- by a later configuration change, an SCell addition, or a numerology difference -- the least important one is the one that goes. Second, check floor(N_CCE,p / L) against nrofCandidates at AL8 and AL16 every time, because that is where budget is wasted on aliased duplicates for no benefit at all.

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

One UE, C-RNTI 0x4C11, in a 40 MHz FR1 TDD cell at 30 kHz subcarrier spacing, physical cell identity 217, TDD pattern DDDDDDDSUU. CORESET 1 is 48 PRB over 2 symbols, 16 CCEs. The same UE and cell as the companion 30 CORESET and Search Space document, so the configuration dumps there and the candidate derivations here describe the same UE.

Figure 9. The sequence the traces below decompose. Only rows 1, 2 and the eventual HARQ-ACK exist anywhere in a network-side log; everything between them has to be reconstructed.

20.1 A candidate-set derivation

[PHY] candidate set derivation, searchSpaceId 1, slot 0
10:24:07.1120  [PHY-DL] PDCCH candidate set, slot 0, SFN 412
  serving cell ............... 0 (PCell)      mu = 1, 20 slots/frame
  C-RNTI ..................... 0x4C11         n_RNTI = 19473
  searchSpaceId .............. 1              ue-Specific
  controlResourceSetId ....... 1              p mod 3 = 1 -> A_p = 39829
  N_CCE,p .................... 16             48 PRB x 2 sym / 6
  n_CI ....................... 0              no cross-carrier config
  hash ....................... Y(1,0) = (39829 * 19473) mod 65537
                                            = 25259
  AL1  M=6  positions=16   base = 25259 mod 16 = 11
     m=0 off=0  -> CCE 11        m=3 off=8  -> CCE  3
     m=1 off=2  -> CCE 13        m=4 off=10 -> CCE  5
     m=2 off=5  -> CCE  0        m=5 off=13 -> CCE  8
  AL2  M=6  positions=8    base = 25259 mod  8 = 3
     m=0 -> CCE  6- 7            m=3 -> CCE 14-15
     m=1 -> CCE  8- 9            m=4 -> CCE  0- 1
     m=2 -> CCE 10-11            m=5 -> CCE  2- 3
  AL4  M=2  positions=4    base = 25259 mod  4 = 3
     m=0 -> CCE 12-15            m=1 -> CCE  4- 7
  AL8  M=2  positions=2    base = 25259 mod  2 = 1
     m=0 -> CCE  8-15            m=1 -> CCE  0- 7
  AL16 M=0                 not searched
  candidates ................. 16
  distinct CCEs covered ...... 16 of 16       -- AL8 alone covers all
  DCI sizes to attempt ....... 2  (60+24=84, 50+24=74)
  decode attempts ............ 32

Listing 6. The derivation from section 5.2, as a UE-side trace would render it. Note the last three lines: sixteen candidates become thirty-two decode attempts because two DCI sizes apply, and the sixteen distinct CCEs are what count against C_max,slot.

20.2 Per-slot budget accounting

[PHY] per-slot budget accounting, slot 2
10:24:07.1121  [PHY-DL] per-slot PDCCH budget, slot 2, SFN 412
  mu = 1  ->  M_max,slot = 36    C_max,slot = 56

  search space sets with an occasion in this slot:
    ssId  type   cs  sym   AL1 AL2 AL4 AL8 AL16   cand   CCE bucket
    ----  -----  --  ---   --- --- --- --- ----   ----   ----------
       4  css     1    0     -   2   1   -    -      3   (cs1,sym0)
       1  uss     1    0     6   6   2   2    -     16   (cs1,sym0)
       2  uss     1    0     4   2   1   -    -      7   (cs1,sym0)
       2  uss     1    8     4   2   1   -    -      7   (cs1,sym8)
       3  css     2    0     1   1   -   -    -      2   (cs2,sym0)
                                                   ----
                                    total candidates  35   <= 36  OK

  non-overlapping CCE buckets:
    (cs1,sym0) union of ssId 4,1,2 ......... 16 CCEs  (0..15)
    (cs1,sym8) union of ssId 2 .............  8 CCEs  (0,1,2,3,4,8,9,12)
    (cs2,sym0) union of ssId 3 .............  3 CCEs  (0,1,2)
                                            ----
                                    total CCEs  27   <= 56  OK

  headroom ................... M: 1 candidate    C: 29 CCEs
  overbooking ................ not triggered
  monitored search spaces .... 1, 2, 3, 4  (all)

Listing 7. The accounting from section 8.3. One candidate of headroom on a configuration that looks unremarkable -- and the next RRCReconfiguration that adds anything at all will trigger dropping.

20.3 An overbooking event

[RRC/PHY] overbooking triggered by an RRCReconfiguration
10:31:52.0080  [RRC-DL] RRCReconfiguration  -- adds searchSpaceId 3, 4
  masterCellGroup/spCellConfig/spCellConfigDedicated
   downlinkBWP-ToAddModList/BWP-Downlink[bwp-Id 1]
    bwp-Dedicated/pdcch-Config/setup/searchSpacesToAddModList
     SearchSpace[0] searchSpaceId 1  controlResourceSetId 1
        searchSpaceType/common/dci-Format2-0        -- SFI monitor
        nrofCandidates AL2 n2, AL4 n2, AL8 n1       -- 5 candidates
     SearchSpace[1] searchSpaceId 2  controlResourceSetId 1
        searchSpaceType/ue-Specific formats0-1-And-1-1
        nrofCandidates AL1 n8, AL2 n8, AL4 n4, AL8 n2  -- 22 candidates
     SearchSpace[2] searchSpaceId 3  controlResourceSetId 2
        searchSpaceType/ue-Specific formats0-1-And-1-1
        nrofCandidates AL1 n6, AL2 n4, AL4 n2       -- 12 candidates
     SearchSpace[3] searchSpaceId 4  controlResourceSetId 1
        monitoringSymbolsWithinSlot 00000010000000  -- symbol 7
        searchSpaceType/ue-Specific formats0-1-And-1-1
        nrofCandidates AL1 n4, AL2 n2, AL4 n2       --  8 candidates

10:31:52.0091  [RRC-UL] RRCReconfigurationComplete
  -- no error, no failure cause. The UE has accepted 47 candidates
  -- against a per-slot limit of 36.

10:31:52.0125  [PHY-DL] per-slot PDCCH budget, slot 4
  configured candidates ...... 47              limit 36
  allocation, common sets first:
    ssId 1  common   +5  -> M=5   C=12         allocated
    ssId 2  ue-spec +22  -> M=27  C=16         allocated
    ssId 3  ue-spec +12  -> M=39  > 36         NOT allocated
    ssId 4  ue-spec       higher ssId than 3   NOT allocated
  monitored .................. ssId 1, 2
  not monitored .............. ssId 3, 4
  -- CORESET 2 has no monitored search space: the UE has stopped
  -- monitoring that CORESET entirely.
  -- No indication of any of this is sent to the network.

Listing 8. The resolution from section 10.2. The RRCReconfigurationComplete is the deceptive line: it confirms the configuration was accepted and says nothing about what will be monitored.

20.4 A successful DCI decode

[PHY] successful blind decode with RNTI-masked CRC
10:24:07.1129  [PHY-DL] PDCCH decode, slot 0, occasion sym 0-1
  attempts 1..12 ............. six AL1 candidates, sizes 84 and 74
                               all CRC fail  (expected -- nothing there)
  attempts 13..26 ............ six AL2 candidates and AL4 m=0,
                               both sizes, all CRC fail
  attempt 27:
    candidate ................ AL4  m=1   CCE 4..7
    DCI size attempted ....... 84 bits  (A=60 + CRC 24)
    coded bits E ............. 432        4 CCE x 108
    descrambling c_init ...... from pdcch-DMRS-ScramblingID 217
    polar decode ............. N=512, SCL list 8, 80 bits shortened
    CRC raw .................. 0x2A7F31
    de-mask: last 16 bits XOR 0x4C11
               0x7F31 XOR 0x4C11 = 0x3320
    computed CRC over payload  0x2A3320
    CRC check ................ PASS  -> DCI is for C-RNTI 0x4C11
  decoded DCI 1_1:
    identifier ............... 1            -- downlink assignment
    bandwidthPartIndicator ... 1            -- configured, OK
    frequencyDomainAssignment  RIV 12483    -- RB 24, L=48, within BWP
    timeDomainAssignment ..... row 6        -- S=2 L=12, K0=0, in range
    mcs ...................... 19           -- 64QAM table, valid
    newDataIndicator ......... 1            -- toggled
    redundancyVersion ........ 0
    harqProcessNumber ........ 3            -- < 16 configured, OK
    downlinkAssignmentIndex .. 1
    pucchResourceIndicator ... 2            -- resource 2 configured
    pdsch-HARQ-timing ........ 1            -- k1=1, slot 1 is UL? no,
                                            -- slot 1 is D; k1 resolved
                                            -- against the PUCCH config
    consistency check ........ PASS
  attempts 28..32 ............ not performed -- candidate matched
  aggregation level used ..... 4
  attempts spent ............. 27 of a possible 32

Listing 9. A successful decode showing the CRC de-mask explicitly. The consistency check line is the validation layer of section 12.2; a false-alarm DCI is what it exists to reject, and it rejects most of them because random payloads rarely satisfy every field range at once.

20.5 The silent failure

[MAC/PHY] grants transmitted into a dropped search space
-- gNB side, after the reconfiguration in 20.3. The scheduler has no
-- knowledge that searchSpaceId 3 is not being monitored.

10:32:14.5000  [MAC-SCH] DL scheduling, slot 4
  ue 0x4C11  buffer 8400 B  cqi 13  target AL 2
  cce allocator: CORESET 1 sym 0 occupancy 12/16, no free AL2 candidate
                 for 0x4C11 -> try CORESET 2 (searchSpaceId 3)
  CORESET 2 sym 0: candidate AL2 m=1 at CCE 2-3 free -> ALLOCATE
  pdcch tx ................... CORESET 2, CCE 2-3, DCI 1_1, 84 bits
  pdsch tx ................... 8400 B, harq 5, ndi toggled

10:32:14.5010  [MAC-SCH] HARQ feedback expected, harq 5, pucch res 2
10:32:14.5015  [PHY-UL] PUCCH decode, slot 6, resource 2
  energy detected ............ no
  result ..................... DTX

10:32:14.5016  [MAC-SCH] harq 5: DTX -> retransmit, rv 2, AL 4
  -- retransmitted into CORESET 2 again, because that is where the
  -- candidate was free. Same outcome.

10:32:14.5040  [MAC-SCH] harq 5: DTX x2 -> outer loop, AL 8
10:32:14.5090  [MAC-SCH] harq 5: DTX x3 -> max retx, discard TB
  rlc: NACK-driven retransmission at RLC AM

-- What the counters show:
--   PDCCH BLER for 0x4C11 ......... 100% on CORESET 2, 0% on CORESET 1
--   CQI ........................... 13, stable
--   RSRP / SINR ................... unchanged, healthy
--   RLC retransmission rate ....... rising
--   UE-reported measurements ...... nothing abnormal
-- The outer loop escalates the aggregation level, which cannot help:
-- the UE is not monitoring that CORESET at any aggregation level.

Listing 10. The silent failure, end to end. The discriminator is in the first counter line: PDCCH BLER that is 100% on one CORESET and 0% on another, for the same UE in the same slots, is not a radio problem. It is an unmonitored search space.

🔍
What you see in logs

Per-CORESET PDCCH statistics are the single most useful thing to have when chasing this, and they are not always collected. If your scheduler reports PDCCH DTX aggregated across CORESETs, the signature in 20.5 averages into a mild elevated BLER that looks exactly like poor coverage. Split it by controlResourceSetId and by searchSpaceId and the fault becomes obvious in one glance.

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

ReleaseWhat changed for blind decodingWhyWhat it means for a log
Rel-15The whole baseline: the hashing function with A_p and D = 65537; per-slot M_max,slot and C_max,slot in Tables 10.1-2 and 10.1-3; the four-size / three-C-RNTI DCI budget and the size-alignment procedure; overbooking with dropping in increasing searchSpaceId order on the PCell; pdcch-BlindDetectionCAEstablishing a bounded UE effort while leaving the scheduler freeEverything in this document except sections 15.5 and the rows below applies to a Rel-15 UE
Rel-16Span-based monitoring with the (X, Y) pairs (7,3), (4,3) and (2,2), and per-span budgets in Tables 10.1-2A and 10.1-3A; monitoringCapabilityConfig-r16 to select the accounting mode; compact DCI formats 0_2 and 1_2 via dci-FormatsExt-r16, participating in the same four-size budget; search space set group switching via searchSpaceGroupIdList-r16; pdcch-BlindDetectionCA-Mixed-r16 for mixed-numerology CAURLLC needed sub-slot grant latency; NR-U and mixed-numerology CA needed accounting that Rel-15 did not haveA UE that stops monitoring mid-connection with no DRX transition is probably a group switch, not a fault. Check searchSpaceGroupIdList-r16 before investigating
Rel-17Multi-slot monitoring for 480 and 960 kHz, with the budgets defined over a group of slots; PDCCH skipping and enhanced search space set group switching, both commanded by DCI; PDCCH repetition through two linked search space sets, with extended counting rules in cl. 10.1 so a linked pair does not simply double the candidate costFR2-2 slots are too short to monitor every one; power saving needed a lever faster than RRC; PDCCH coverage needed something better than AL16Monitoring that stops on command looks identical to overbooking in a PHY log. The discriminator is a preceding DCI -- if there is one, it was deliberate
Rel-18Multi-cell scheduling with a single DCI, which changes candidate accounting because one candidate now schedules more than one cell; further reduced-monitoring UE features; low-power wake-up signalling that removes monitoring occasions entirely while idleReducing the per-cell PDCCH cost of large carrier-aggregation configurations, and cutting idle-mode powerCandidate counts per scheduled cell no longer scale linearly with cell count. Recheck section 14's arithmetic against the release the UE actually reports

Table 25. Release deltas. Rel-15 defines the mechanism; every later release adds a way to spend the budget differently rather than a way to enlarge it.

🔄
Release delta

The releases have not changed the fundamental bargain and are unlikely to. M_max,slot at 30 kHz has been 36 since Rel-15 and remains 36. Every enhancement since has been about where the 36 are spent -- concentrated in a span, spread over a group of slots, shared between cells, or skipped altogether. When you see a new monitoring feature, the first question is always which existing candidates it displaces.

22. Reading Blind Decoding in Logs: A Checklist

Ordered for a UE that is connected, measures well, and is not being scheduled reliably. Steps 1 to 4 are arithmetic on the configuration and need no capture at all; do them before anything else, because they are the only way to see the silent failures.

  1. Sum the candidates. Take the last RRCReconfiguration, list every search space set with an occasion in the same slot, multiply by the number of occasions per slot, and add the five nrofCandidates values for each. Compare against M_max,slot for the numerology: 44 / 36 / 22 / 20 at 15 / 30 / 60 / 120 kHz. If it exceeds, you already know which search spaces are being dropped -- the highest searchSpaceId values (section 10.1).
  2. Sum the non-overlapping CCEs, and do it separately even if step 1 passed. Group by (CORESET, first symbol of the occasion), take the union of the candidate CCEs in each group, add the group sizes, compare against C_max,slot: 56 / 56 / 48 / 32. A configuration can pass step 1 and fail this one, and the fix is completely different (section 8.4).
  3. Count the DCI sizes. Distinct payload sizes across all monitored search spaces, and separately the distinct sizes for C-RNTI-scrambled DCI. Four and three. If you are at the limit, look for a truncated frequency-domain assignment in the fallback formats (section 9.2).
  4. Check pdcch-BlindDetectionCA against the configured downlink cell count. If cells exceed capability, redo steps 1 and 2 against the scaled per-cell limits, and note that the PCell is scaled too (section 14.1). This step is the one most often skipped and it explains the largest share of "it worked before we added the SCell".
  5. Confirm the C-RNTI is the same on both sides. The C-RNTI seeds the hash. Check the value in the last RRCReconfiguration or MSG4 against the value the scheduler is using. A mismatch means the UE is searching a different rotation of the CORESET and nothing will ever be found (section 4.1).
  6. Check nrofCandidates at the aggregation level the scheduler wants. An aggregationLevel8 of n0 makes AL8 unreachable in that search space regardless of coverage, and an aggregationLevel16 of n2 in a 16-CCE CORESET is two aliased copies of one candidate (section 5.4).
  7. Split PDCCH BLER and DTX by controlResourceSetId and searchSpaceId. This is the single highest-value log change you can make in this area. 100% DTX on one CORESET and 0% on another, for the same UE in the same slots, is an unmonitored search space and not a radio problem (section 20.5).
  8. Compare the aggregation-level histogram against the cell's coverage profile. All AL1 suggests under-protection; all AL8 and AL16 suggests a CORESET too small for its load. A histogram that shifted upward with no radio change usually means the DCI got bigger -- look for a newly enabled optional DCI field (section 13.2).
  9. Look for PDCCH blocking counters rising with load while PDCCH BLER stays flat. That is candidate collision, not link quality, and the answer is a larger CORESET or more monitoring occasions rather than a lower code rate (section 6.3).
  10. If you see unexplained uplink energy, check the false-alarm hypothesis. Correlate the transmission timing with a monitoring occasion plus a plausible K2. A UE with a heavy candidate x DCI-size product is a credible source (section 12.3).

23. Glossary

TermExpansionWhat it means in this document
CandidatePDCCH candidateL consecutive CCE indices in one CORESET at one occasion, and one unit of the M_max,slot budget
ALAggregation levelThe number of CCEs a PDCCH occupies: 1, 2, 4, 8 or 16. Sets the code rate, and the only reliability lever PDCCH has
CCEControl channel elementSix REGs, 108 usable QPSK coded bits. The allocation unit for PDCCH and the unit of the C_max,slot budget
Y_p,nThe hashing function outputThe per-UE, per-slot, per-CORESET rotation applied to the candidate positions. Zero for a common search space
A_pHash multiplier39827, 39829 or 39839 selected by p mod 3, where p is the controlResourceSetId
M_max,slotMaximum monitored candidates per slot44 / 36 / 22 / 20 by numerology, per serving cell. Bounds decoder attempts
C_max,slotMaximum non-overlapping CCEs per slot56 / 56 / 48 / 32 by numerology, per serving cell. Bounds channel estimation
Non-overlapping-- (of CCEs)Distinct in (CORESET, first symbol, CCE index). Two candidates sharing all three share one channel estimate and count once
Overbooking-- Configuring more candidates or CCEs than the budget allows. Resolved by the UE not monitoring the highest-numbered UE-specific search spaces
n_CICarrier indicator field valueThe CIF value, 0 to 7, which rotates a scheduled cell's candidates away from the scheduling cell's
Span-- (Rel-16)A window of consecutive symbols containing all of a UE's monitoring occasions, characterised by (X, Y) and carrying its own budget
(X, Y)Span separation and lengthX = minimum symbols between span starts, Y = maximum span length. (7,3), (4,3) and (2,2) are the defined pairs
False alarm-- A candidate whose CRC passes after RNTI de-masking although no DCI was transmitted there
Aliasing-- (of candidates)Two distinct candidate indices m mapping to the same CCEs, which happens when M_p,L exceeds floor(N_CCE,p / L)
Size alignmentDCI size alignmentThe TS 38.212 procedure that pads and truncates DCI formats until the four-size and three-C-RNTI-size budgets are met

Table 26. Terminology used here, in the sense this document uses it. Where a term also appears in the companion 30 CORESET and Search Space document it carries the same meaning.

24. References

  • 3GPP TS 38.213 -- Physical layer procedures for control. Clause 10.1 is the primary reference for this entire document: the search space types, the monitoring occasion derivation, the candidate hashing function with A_p, D and the recursion, the candidate-to-CCE mapping formula, the per-slot limits in Tables 10.1-2 and 10.1-3, the per-span limits in Tables 10.1-2A and 10.1-3A, the definition of non-overlapping CCEs, the overbooking and dropping rules, and the carrier-aggregation scaling of the limits. Clause 10.2 (PDCCH validation for downlink SPS and configured uplink grants -- the one place the specification says a validation failure is treated as a CRC failure). Clause 9.2 (PUCCH resource determination, which the HARQ timing consistency check uses). Clause 11.1 (slot configuration, and the interaction between monitoring occasions and uplink symbols). Clause 12 (bandwidth part operation).
  • 3GPP TS 38.212 -- Multiplexing and channel coding. Clause 7.3 (downlink control information): 7.3.1 for the DCI formats and their field-by-field composition, which fixes every payload size used in this document; 7.3.1.0 for the DCI size alignment procedure and the padding and truncation rules; and the CRC attachment with RNTI scrambling, which is where the 24-bit g_CRC24C CRC and the XOR of the 16-bit RNTI into its last 16 bits are specified. Clause 5.1 (CRC calculation and the CRC polynomials). Clause 5.3.1 (polar coding, the mother code length selection with n_max = 9 for downlink control) and clause 5.4.1 (rate matching for polar codes, i.e. the shortening and repetition behaviour in section 11.2).
  • 3GPP TS 38.211 -- Physical channels and modulation. Clause 7.3.2 (PDCCH): 7.3.2.1 (scrambling, and the initialisation from pdcch-DMRS-ScramblingID and the C-RNTI), 7.3.2.2 (CCE-to-REG mapping, which decides where a candidate's CCEs physically sit), 7.3.2.3 (PDCCH DMRS sequence generation). Clause 7.4.1.3 (PDCCH DMRS mapping to resource elements, i.e. the 3-in-12 DMRS density that leaves 9 data REs per REG).
  • 3GPP TS 38.331 -- RRC protocol specification. PDCCH-Config and PDCCH-ConfigCommon; SearchSpace, SearchSpaceId and maxNrofSearchSpaces; ControlResourceSet, ControlResourceSetId and maxNrofControlResourceSets; the nrofCandidates field descriptions, which carry constraints not visible in the ASN.1; searchSpaceGroupIdList-r16 and searchSpaceSwitchTimer-r16; monitoringCapabilityConfig-r16 in ServingCellConfig; CrossCarrierSchedulingConfig and cif-InSchedulingCell.
  • 3GPP TS 38.306 -- UE radio access capabilities. pdcch-BlindDetectionCA and pdcch-BlindDetectionCA-Mixed-r16; pdcch-MonitoringAnyOccasions and pdcch-MonitoringAnyOccasionsWithSpanGap with the set1 / set2 / set3 encoding of the (X, Y) pairs; the Rel-17 multi-slot monitoring capabilities.
  • 3GPP TS 38.214 -- Physical layer procedures for data. Clause 5.1 (PDSCH reception, the HARQ process count, and the field-range constraints that the consistency check in section 12.2 enforces); clause 5.1.2.2 (resource allocation types and the RIV decoding that bounds a valid frequency-domain assignment).
  • 3GPP TS 38.321 -- MAC protocol specification. Clause 5.7 (DRX and Active Time, which gates every monitoring occasion and therefore every candidate).
  • 3GPP TS 38.300 -- NR overall description. Clause 6 (downlink physical layer structure); clause 10 (the scheduling framework the grants found here belong to).

Companion documents in this set

  • 03 Random Access -- the RA-RNTI and TC-RNTI blind decodes a UE performs before it has a C-RNTI, and the contention resolution that assigns the C-RNTI this document's hash is seeded with.
  • 05 HARQ -- why a missed PDCCH produces neither an ACK nor a NACK, and how DTX inference lets the scheduler notice anyway.
  • 08 Scheduling -- the survey-level view of DCI formats, resource allocation and the blind-decode budget; this document goes underneath its section 5.
  • 11 DRX -- Active Time, the dominant reducer of monitoring occasions and therefore of candidates, in any power-saving configuration.
  • 19 Paging -- blind decoding for P-RNTI in RRC_IDLE and RRC_INACTIVE, where the same machinery runs with Y = 0.
  • 22 Handover Overview -- where the C-RNTI changes, and therefore where the whole candidate set relocates.
  • 26 UE Capability -- pdcch-BlindDetectionCA, pdcch-MonitoringAnyOccasionsWithSpanGap, and everything else that must be confirmed before a monitoring configuration means anything.
  • 29 Carrier Aggregation -- n_CI and the carrier indicator field, cross-carrier scheduling, and the per-UE apportionment of the blind-decode budget across serving cells (section 14).
  • 30 CORESET and Search Space -- the configuration side: ControlResourceSet and SearchSpace field by field, frequencyDomainResources, the CCE-to-REG mapping that decides where a candidate's CCEs physically land, and the derivation of the monitoring occasions this document consumes. That document produces the input; this one consumes it.
  • 32 SLIV and Time Domain Allocation -- the time-domain assignment field the decoded DCI carries, and the row-index range that the consistency check in section 12.2 validates against.
  • 33 DMRS -- the PDCCH DMRS structure that every channel estimate in the C_max,slot budget is formed from, and the scrambling initialisation that a descrambling mismatch breaks.
  • 34 Link Adaptation -- the aggregation-level selection loop of section 13, the outer-loop correction that responds to PDCCH DTX, and the MCS selection it shares its machinery with.
  • 35 Physical Channels -- where PDCCH sits among the other physical channels, and the resource-element-level mapping of all of them.