Skip to content
fundamentals

What is a Solana shred FEC set?

A Solana FEC set is one recovery group containing consecutive data shreds and coding shreds derived from them. The FEC set index anchors the source range. Coding headers declare data count, coding count, and parity position. Any valid subset at least as large as the data count can reconstruct every source shred in the set.

protocol desk · updated 2026-08-31

1 set is one recovery problem

An FEC set is the smallest independent Reed-Solomon recovery group in Solana's shred stream. It contains a consecutive run of data shreds and parity shreds computed from equal-length representations of those data shreds.

The boundary matters. A coding shred from one set cannot repair a data shred from another, even when both belong to the same slot. Their equations were built from different source vectors. Recovery code must partition packets correctly before counting them.

The common FEC set index supplies the group anchor. Coding headers supply dimensions and coding position. Merkle variants also use the FEC set as the authentication tree boundary. One grouping decision therefore controls repair, proof verification, duplicate isolation, memory ownership, and the point at which temporary state can be released.

The anchor is a data index

The FEC set index is a 32-bit value carried in the common header of both data and coding shreds. It identifies the first data-shred index in the recovery group.

If an FEC set index is 128 and its validated data count is 32, the source range is data indexes 128 through 159. The next typical set might begin at 160. Receivers should derive the actual range from the anchor and declared shape, then check that each data member belongs inside it.

The anchor is not a slot-wide ordinal such as set four. It is already expressed in data-index coordinates. This makes data placement direct and lets a receiver group early data packets before a coding header has arrived. It also means arithmetic needs overflow and slot-bound checks before allocation.

Set size is bounded, not universal

Current implementations target groups of 32 data shreds during ordinary shredding. The actual number in a set can differ, especially at a serialization boundary where fewer source shreds remain.

Treating 32 as a permanent wire constant is brittle. Coding headers declare the source and coding counts. Variant rules, implementation limits, and cross-member consistency determine whether those declarations are admissible.

Bounded sets keep Reed-Solomon work manageable and limit how long a single missing packet blocks recovery. They also bound Merkle proof height. A single slot-wide matrix might improve aggregate coding efficiency, but it would delay parity generation, enlarge state, and make one inconsistency affect far more data.

Three numbers define the matrix

Recovery needs the FEC set anchor, data count, and coding count. Coding position then identifies one parity row. Slot and variant family provide additional grouping and layout context.

A declaration of 20 data and 20 coding shreds creates 40 possible shard positions. Source positions zero through 19 map to data indexes anchor through anchor plus 19. Parity positions map after the source portion in the Reed-Solomon shard array, even though their coding header position starts at zero.

Any 20 independent, valid members are sufficient in the intended erasure model. The receiver can have all 20 data and need no computation, 19 data plus one coding, or 7 data plus 13 coding. The threshold does not depend on which source indexes are absent.

Data arrives before complete metadata

Data headers carry the FEC set index but not the set's data and coding counts. A receiver can therefore see several data shreds before any coding shred declares the matrix dimensions.

Provisional grouping should be sparse and bounded. Store valid data members by their common index under slot and FEC anchor. Do not assume the target size and allocate a full matrix for every unverified packet. When a sanitized coding header arrives, reconcile the provisional members against its declared range.

If no coding shred arrives, complete consecutive data can still be decoded. FEC metadata is required for recovery, not for ordinary ordered assembly. This separation prevents parity delays from holding up a clean data path.

Completion and FEC boundaries differ

A DATA_COMPLETE flag ends one serialized vector of entries. An FEC set boundary ends one recovery group. Those boundaries can coincide, but they describe different layers and must not be treated as synonyms.

One completed entry batch can span multiple FEC sets. One FEC set can contain a data-complete marker before its final source shred if the leader begins another serialized batch within the same recovery grouping behavior supported by the implementation.

Receivers track both. The FEC lane asks whether enough shards exist to reconstruct source packets. The assembly lane asks whether a consecutive data-index range reaches a completion marker. Advancing either frontier based on the other's metadata can release incomplete bytes or retain already decodable data.

Merkle trees use the same boundary

For Merkle shreds, the leader constructs a canonical tree over the data and coding shreds in the FEC set. Data leaves appear in sequence, followed by coding leaves in sequence. The signed root commits to the set.

Each packet carries a branch that lets the receiver recompute the root from that shred's leaf. All members of a consistent set reach the same leader-signed root. Different roots under the same slot and anchor describe a conflict and must not be mixed for recovery.

This coupling is useful. Erasure reconstruction and authentication refer to the same bounded group. It also means count metadata affects proof interpretation. A receiver must validate dimensions and proof size rather than accepting a branch merely because its final hash has a valid signature.

Recovery begins at the threshold

The source count is the recovery threshold. A 32-source set with 30 data and 2 coding shreds is recoverable. A set with 29 data and 2 coding shreds is not.

Duplicates do not help. Two copies of coding position seven represent the same equation. Conflicting copies cannot both be admitted. The shard count must measure distinct validated source indexes and coding positions within one consistent set view.

Recovery can start as soon as a gap blocks useful data and the threshold is met. Waiting for every possible parity shred adds latency. Running recovery when no source gap exists adds CPU. A receiver should expose both total unique member count and missing-source count so the trigger remains explicit.

Failure beyond parity capacity

A set with k source shreds and m coding shreds tolerates up to m erasures only when at least k valid total members survive. Loss beyond that threshold leaves multiple possible source vectors consistent with the observed rows.

No local algorithm can infer the missing bytes from insufficient information. The receiver must wait for additional direct or coding shreds, request repair from peers, obtain the block through another source, or abandon the set for its current latency objective.

Authentication does not change the threshold. A valid signature proves a surviving member belongs to a committed view, but it does not generate the missing equations. Likewise, receiving many invalid packets does not improve recovery capacity.

Conflicting metadata needs partitioning

Untrusted UDP can carry two coding shreds with the same slot and FEC anchor but different source counts. It can carry different Merkle roots, repeated positions with different bytes, or data indexes outside the declared range.

Do not let the first packet permanently define a set without evidence. Sanitize each member, authenticate it, and partition conflicts by authenticated commitment where the variant provides one. Set a low bound on concurrent conflicting views and preserve metrics when the bound is exceeded.

Last-write-wins behavior is particularly unsafe. Replacing one coding position after other rows were admitted can make a matrix internally inconsistent. A failed reconstruction should not be retried across arbitrary combinations forever. Bound attempts and escalate the conflict as protocol evidence.

Memory follows active sets

At 5,585 packets per second, even short retention creates many live packet objects. FEC grouping adds maps, presence bitmaps, proof state, and optional raw-byte retention.

Use a slot horizon and per-slot set cap. Validate count fields before sizing arrays. Store presence in fixed or bounded bitsets once dimensions are known. Release coding payloads after source completeness unless diagnostics require a brief sample. Keep reconstructed data until the assembly lane consumes it.

Eviction should distinguish complete, unrecoverable, and stale. A complete set can be freed promptly. An unrecoverable set may deserve a short repair window. A future-slot spam set should never displace authenticated current-slot state merely because its numeric slot is larger.

Metrics that expose real loss

Packet-drop counters alone do not describe FEC health. A receiver needs unique data count, unique coding count, recovered source count, threshold wait time, reconstruction duration, invalid member count, and conflict count by set.

Track the first-arrival and recoverable timestamps. Their difference shows how long redundancy took to close a gap. Track when the ordered data frontier consumed the recovered shred. That measures whether FEC was on the critical path for entry decoding.

Do not call every absent data index lost immediately. Reordering is normal. A useful loss metric applies a short observation window or records eventual recovery outcome. Separating reordered, recovered, repaired, and permanently absent packets makes network tuning possible.

FEC state is not consensus state

Completing an FEC set means the receiver has enough authenticated bytes to reconstruct one part of a proposed slot. It says nothing about later votes, fork choice, execution success, or rooting.

The set can belong to a duplicate block. It can be complete while an earlier FEC set in the same slot remains absent. A terminal set can include LAST_IN_SLOT while the receiver still lacks source data in a previous group.

Use names such as set_recoverable, set_data_complete, entry_batch_complete, slot_data_complete, and slot_rooted for separate milestones. These states have different evidence and different consumers. Collapsing them into complete creates race conditions in both trading and archival systems.

A practical set state machine

NEW begins with one sane member. SHAPED begins when validated coding metadata establishes dimensions. RECOVERABLE begins when distinct member count reaches source count. SOURCE_COMPLETE begins when every data position is present, directly or after reconstruction.

CONSUMED means ordered assembly no longer needs the set's data bytes. CONFLICTED records incompatible authenticated claims. EXPIRED records eviction before source completion. A set can move from NEW directly to SOURCE_COMPLETE when all data arrives without coding metadata.

The state machine should be monotonic except for explicit conflict discovery. Late duplicate packets do not reopen consumed state. Late evidence of a conflicting authenticated root should increment a durable diagnostic signal even if the strategy path has already discarded the old payloads.

Path diversity changes set outcomes

FEC success depends on which distinct positions survive, not only the aggregate packet-loss percentage. Losing 20 packets spread across 20 different sets may require one parity shard in each. Losing the same 20 packets inside a 16-plus-16 set can make that one set unrecoverable.

Multiple delivery paths can reduce correlated erasures when their loss domains differ. Duplicate traffic adds bandwidth, but a second copy arriving through the same congested queue may add little independence. Record transport path beside shred identity before deduplication so operators can measure which path supplied the first valid copy and which path closed a recovery threshold.

Set-level histograms expose concentration. Track missing-source count at first completion marker, members available at recovery time, and unrecoverable sets by slot. One global loss rate can look healthy while a few concentrated gaps block the transaction batches with the highest latency value.

In practice

Slot 330,118,604 contains an FEC set anchored at data index 64. A coding shred declares 24 data shreds and 24 coding shreds, so the source range is indexes 64 through 87.

Indexes 64 through 87 arrive except 71, 72, and 85. Coding positions 0, 4, 9, and 17 also arrive. The receiver has 21 distinct data members plus 4 distinct parity members, 25 total. The recovery threshold is 24.

One of the 25 is excluded because its Merkle branch reaches a different root. The remaining 24 consistent members still meet the threshold. Reed-Solomon recovery reconstructs the three missing data shreds. Index 85 carries DATA_COMPLETE, so the assembly lane can now deserialize the batch ending there. Coding position 4 arriving again does not alter the count.

What this does not cover

This page treats an FEC set as the receiver's recovery and authentication unit. It does not derive finite-field equations, define every Merkle chaining byte, or prescribe repair-service behavior after local recovery fails.

The current implementation target of 32 data shreds is an implementation behavior, not a value that consumers should hard-code as the only valid set shape. On-wire counts still require protocol-aware bounds, cross-member agreement, and variant-specific validation.

Related questions

What does the FEC set index mean?
The FEC set index is the data-shred index at which one recovery group begins. If the anchor is 128 and the validated data count is 32, source indexes span 128 through 159. Data and coding shreds share the anchor, while coding headers provide the counts and parity positions needed for recovery.
Are all Solana FEC sets 32 data shreds?
No. Current shredding targets bounded groups of 32 data shreds, but actual groups can be smaller at serialization boundaries and protocol behavior can evolve. Receivers should parse sanitized data and coding counts, enforce supported limits, and verify agreement across members instead of requiring one hard-coded group size.
When is an FEC set recoverable?
A set becomes recoverable when the number of distinct, valid, mutually consistent data and coding shards reaches the declared data-shred count. A 24-source set needs 24 total members in any source-parity combination. Repeated copies of one packet or coding position do not increase the independent count.
Is a complete FEC set a complete slot?
No. One slot usually contains multiple recovery groups. Completing one set reconstructs only its source range. Slot data is complete after every data index through a valid last-in-slot marker is present. Consensus confirmation and rooting occur later and remain separate from local packet completeness.
Can shreds with different Merkle roots share a recovery set?
No. Different authenticated Merkle roots under the same slot and FEC anchor represent conflicting set views. Mixing their shards can corrupt recovery or make it fail. Receivers should partition or quarantine conflicting roots, bound retained evidence, and never count members across those views toward one recovery threshold.

Read next

Ready to build against this? The documentation covers the implementation.