Which fields are in a Solana shred header?
A Solana shred header has six common fields: signature, variant, slot, index, shred version, and FEC set index. Data shreds add parent offset, flags, and size. Coding shreds add the declared data-shred count, coding-shred count, and coding position. Receivers validate fields together because no single field makes a packet trustworthy.
protocol desk · updated 2026-08-31
12 fields, two header families
Six fields appear in every current shred: signature, variant, slot, index, shred version, and FEC set index. Three more appear on data shreds: parent offset, flags, and size. A different three appear on coding shreds: number of data shreds, number of coding shreds, and coding position.
The list looks like a record schema, but a receiver should read it as a set of linked claims. Slot selects an expected leader. Signature attributes content to that leader. Version binds the packet to a network lineage. Index and FEC set index place the packet in two overlapping orderings. Counts and position define a recovery matrix.
Validation therefore happens across fields. A syntactically valid index can still be impossible for the slot. A valid signature can cover a packet for the wrong cluster version. A coding position can be within a machine integer range but outside its declared coding count.
Signature: 64 bytes of attribution
The first 64 bytes hold an Ed25519 signature. The expected public key comes from the leader schedule for the claimed slot. The signed message depends on the variant.
Legacy shreds sign packet bytes after the signature field. Merkle shreds sign a Merkle root recovered from the shred leaf and its proof. Every shred in one Merkle FEC set can carry the same root signature, so equal signatures within that set are expected rather than evidence of duplicate packets.
Signature verification answers a narrow question: did the holder of the expected leader key authenticate the relevant bytes or root? It does not answer whether the slot won fork choice, whether an embedded transaction executed, or whether the packet arrived by an approved network path. Keep attribution separate from consensus status and transport provenance.
Variant: one byte of parser control
The variant field selects data versus coding and legacy versus Merkle authentication. Merkle patterns also carry proof-size information and flags for chained or resigned forms.
This byte must be decoded before the receiver chooses payload boundaries or a signature message. It affects usable data capacity because proof material consumes packet space. It affects erasure coding because legacy and Merkle variants expose different byte ranges as source shards. It also affects validation rules for chaining material.
Unknown values should fail closed and increment a compatibility metric. Masking away unfamiliar high bits or treating every non-data value as coding is unsafe. A future activation can make previously invalid patterns meaningful, but only software that implements the corresponding layout can consume them correctly.
Slot: the primary time coordinate
The slot is an unsigned ledger coordinate, not a wall-clock timestamp. It places the shred in a leader opportunity and selects the leader identity used for authentication.
Slots can be skipped, abandoned, or present on competing forks. The integer does not promise that a block exists or will become canonical. A receiver commonly maintains a moving acceptance window around its observed cluster tip, rejecting ancient replay traffic and implausibly distant future values before expensive verification.
Do not derive milliseconds by multiplying slot count by a fixed duration. Slot timing is a target shaped by ticks, scheduling, and network conditions. Record local receive time separately. The pair of protocol slot and monotonic arrival timestamp supports both ledger assembly and transport-latency analysis without confusing the two clocks.
Index: position inside a type
The common index is a 32-bit sequence number interpreted with shred type. Data index zero is the first data shred of the slot, followed by one, two, and so on. Coding shreds occupy their own type namespace.
Arrival order has no effect on index meaning. Data index 81 can arrive before index 80. A duplicate copy can arrive from another path. A recovered data shred must be inserted at its encoded index, not appended when recovery completes.
Use the tuple of slot, type, and index as the identity key. Adding version to an admission key can be useful before filtering, but accepted storage should not retain incompatible versions in the same slot assembly. FEC set index remains a separate grouping coordinate rather than part of basic order.
Shred version: cluster lineage filter
The two-byte shred version helps prevent packets from one network or ledger lineage from being accepted into another. Validators derive the expected value from genesis-related state rather than negotiating it per packet.
The version is an early and inexpensive reject condition. A receiver configured for mainnet should compare the parsed value with its configured expectation before signature verification or FEC allocation. This blocks a large class of cross-cluster noise.
Version equality is necessary but not sufficient. It does not authenticate the sender, prove the leader, or guarantee compatible variant support. A custom cluster can share software while having a different version. Conversely, software upgrades can preserve the expected shred version while adding a newly activated variant that still requires decoder support.
FEC set index: recovery-group anchor
The FEC set index identifies the data-shred position at which an erasure set begins. All data and coding shreds admitted to one set must agree on this value and on the set's other structural metadata.
For a group beginning at data index 96, the value 96 anchors the source range. If the set declares 32 data shreds, the intended data indexes run from 96 through 127. The final group in a data batch can be smaller, so code should use declared and validated metadata rather than assuming every set reaches a target count.
The field does not itself say how many shards exist. Coding headers provide counts and positions. A receiver may need a coding shred before it knows the full matrix shape. Until then, data shreds can be buffered by slot and FEC set index without allocating an unbounded shard array.
Parent offset: linking slot ancestry
Data shreds carry a two-byte parent offset. Subtracting that offset from the current slot yields the claimed parent slot. An offset of one links to the immediately preceding slot. A larger value crosses one or more skipped slots.
The representation is a distance because the parent is always earlier. Validation rejects zero, underflow, and values that cannot produce an admissible parent. All data shreds in the same slot should agree on the parent relationship.
Parent information begins a ledger edge, but it does not settle fork choice. Two leaders or duplicate production can expose conflicting authenticated data for a slot. The broader replay and consensus pipeline determines which ancestry is viable. A raw receiver should preserve enough conflict evidence to avoid silently merging data from different proposed blocks.
Flags: completion plus reference tick
One byte on data shreds contains a six-bit reference-tick value and two high-bit completion signals. DATA_COMPLETE marks the end of a serialized entry batch. LAST_IN_SLOT marks the terminal data shred of the slot and also implies data completion.
The distinction matters. A slot can contain several completed data batches before its final shred. Consumers can deserialize and process a completed prefix without waiting for the slot-ending flag. That is one source of the latency advantage in direct shred consumption.
Flag combinations require validation. A last-in-slot indication without data completion is not valid under the current definition. Reference tick is useful for placement and sanity checking, but it is not a wall-clock reading and should not replace receive timestamps or full Proof of History verification.
Size: the meaningful data boundary
The two-byte size field on a data shred marks the end of the meaningful serialized data region relative to the packet layout. It prevents padding and trailing authentication material from entering the entry decoder.
Size must be large enough to include the required headers and no larger than the variant permits. It must also fit inside the received datagram. A claimed size of 1,200 cannot be honored if UDP delivered only 900 bytes. Reading past the datagram is a memory-safety error in low-level languages and a parse-corruption error everywhere else.
Do not infer size from datagram length. Fixed packet shaping, zero padding, proofs, chaining roots, and retransmitter signatures can all make the outer packet longer than the ledger byte range. The field and variant-specific layout jointly define the boundary.
Data and coding counts
Coding shreds declare how many source data shards and parity shards belong to the FEC set. These unsigned 16-bit fields determine the recovery threshold and matrix dimensions.
A declaration of 24 data and 24 coding shreds describes 48 total positions. Any 24 consistent shards should be sufficient to recover the 24 source shards. Receiving 23 cannot be repaired regardless of how many times those same packets were duplicated.
Counts are untrusted until sanitized. Zero values, implementation-limit violations, arithmetic overflow, and disagreement among set members require rejection or quarantine. Allocating memory directly from an unchecked network count creates a denial-of-service path. Cache only validated Reed-Solomon configurations and place hard operational bounds around pending sets.
Coding position: parity coordinate
The coding position numbers a parity shred within the coding portion of an FEC set. It ranges from zero up to, but not including, the declared number of coding shreds.
Position is not the data index to be reconstructed. It selects a row of the coding matrix. A parity packet at position seven can help recover any missing source position when combined with enough other independent shards. Naming the field recovery target in application code usually predicts a later mapping bug.
The common coding-shred index and the position serve different protocol functions. The common index identifies the coding shred in its slot-wide type sequence. Position locates its erasure row inside one FEC set. Store both, validate their consistency, and use position when building the Reed-Solomon shard vector.
Cross-field validation
Useful invariants span the header. Variant type must match the selected data or coding parser. Slot must lie inside the receive window. Version must match the configured cluster. Data parent offset must not underflow. Size must fit the selected variant and datagram.
For coding shreds, position must be below coding count. Counts must stay within implementation bounds. Members grouped under one slot and FEC set index must agree on dimensions, variant family, Merkle root, and other set-level commitments.
For data shreds, index must fall into the range implied by the FEC anchor when the set shape is known. Completion markers must be monotonic with ordered assembly. A last-in-slot marker at index 211 makes a later authenticated data index 212 a conflict requiring explicit handling, not an invitation to extend the slot.
Header fields are not state
Every header value is a claim carried by an untrusted datagram until parsing, sanitization, and authentication succeed. Even authenticated values describe a leader proposal, not final ledger state.
This principle changes API design. Return a parsed header separately from an admitted shred. Attach validation status and reason codes. Do not let an observability path accidentally feed unsanitized indexes into production allocation logic. Preserve raw bytes for a bounded time when diagnosing conflicts.
The fields become useful in stages: bytes produce a parsed claim, cheap invariants produce a sane candidate, version and leader checks produce an authenticated packet, FEC processing produces missing data, and ordered deserialization produces entries. Consensus later decides whether the corresponding block matters.
In practice
A receiver gets a coding shred for slot 322,004,118 with common index 517, version 31, and FEC set index 224. Its coding header declares 32 data shreds, 32 coding shreds, and position 5.
The receiver first confirms that version 31 is its configured cluster value and that slot 322,004,118 is inside its active window. Position 5 is below the coding count of 32. The recovery group is keyed by slot 322,004,118 and FEC anchor 224. Its source indexes are expected to cover 224 through 255.
Twenty-nine data shreds and four distinct coding positions are already present. That makes 33 valid shards for a 32-source set. The decoder chooses 32, reconstructs three absent data shards, sanitizes their parent offsets, flags, and sizes, and inserts them by data index. Common coding index 517 never becomes a data destination. Coding position 5 supplies one independent recovery row.
What this does not cover
This page explains current header semantics and the validation relationships among fields. It does not provide copy-and-paste offsets for every Merkle, chained, or resigned payload tail. Variant-specific code should follow the Agave implementation and the active network feature set.
Header validation also does not replace leader-schedule maintenance, Merkle proof verification, Reed-Solomon recovery, entry decoding, or consensus reconciliation. A field can be well formed and authenticated while the proposed slot later loses its fork.
Related questions
- Which fields appear in every Solana shred?
- Every current shred carries a 64-byte signature, a one-byte variant, an eight-byte slot, a four-byte index, a two-byte shred version, and a four-byte FEC set index. Those fields form the 83-byte common header. Data and coding shreds then append different type-specific header fields.
- What does the data-complete flag mean?
- The data-complete flag marks the final data shred in one serialized entry batch. Consecutive data shreds through that index can be concatenated and decoded once gaps are filled. It does not necessarily end the slot. The separate last-in-slot flag marks the terminal slot shred and also implies data completion.
- Is the FEC set index the same as the shred index?
- No. The shred index identifies one packet within the slot's data or coding sequence. The FEC set index anchors a recovery group at a data-shred index. Many shreds share one FEC set index. Receivers use slot, type, and index for identity, then slot and FEC set index for recovery grouping.
- Why does a coding shred have both index and position?
- The common index identifies the coding shred in the slot-wide coding sequence. Coding position identifies the parity row inside one FEC set and ranges from zero to one below the coding count. Reed-Solomon assembly uses position. Packet deduplication and storage use the common slot, type, and index identity.
- Can the slot field be converted directly to a timestamp?
- No. A slot is a consensus and leader-schedule coordinate, not a wall-clock timestamp. Target timing and actual production can differ, and skipped slots still consume coordinates. Latency systems should store a monotonic local receive timestamp beside the slot rather than derive precise arrival time from slot arithmetic.
Read next
Ready to build against this? The documentation covers the implementation.