Skip to content
fundamentals

Which fields are in a Solana shred header?

All Solana shred headers begin with signature and variant, followed by slot, index, shred version, and FEC set index. A data header then supplies size, flags, and parent offset. A coding header instead declares source-shard total, parity-shard total, and parity position. Receivers validate the relationships because no field alone makes a packet trustworthy.

protocol desk · updated 2026-08-31

12 fields, two header families

Every current shred starts with six shared fields. Signature and variant lead; slot, index, version, and FEC anchor follow. Data packets next encode their size, parent offset, and flags. Coding packets instead provide parity position plus separate counts for source and parity members.

Although this resembles a record schema, each value constrains several others. Slot selects an expected leader. Signature attributes content to that leader. Version binds the packet to a network lineage. The index orders one shred type, while the FEC anchor identifies its recovery group. Counts and position determine matrix geometry.

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. For the claimed slot, the leader schedule supplies the public key that verification should expect. Variant determines how the signed message is constructed.

For a legacy shred, the signed message is the packet region following its signature. A Merkle shred authenticates a root computed from its leaf plus proof. Members of one Merkle FEC group may therefore repeat a root signature without being 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 uses 32 bits and gains meaning from shred type. Data index zero begins the slot's data sequence, then one and two follow. A separate namespace holds coding indexes.

Arrival order has no effect on index meaning. Data index 81 can arrive before index 80. A duplicate copy can arrive from another path. After recovery, placement follows the encoded data index rather than completion time.

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

Two version bytes help stop traffic from one network or ledger lineage entering another. Validators derive their expected value from genesis-related state instead of negotiating 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 match supplies one admission condition among several. It neither authenticates a sender nor establishes the leader, and says nothing about support for the selected variant. A custom cluster can share software while using another value. Conversely, an upgrade may retain the existing version yet activate a variant that older decoders cannot parse.

FEC set index: recovery-group anchor

The FEC set index names the data position where an erasure group starts. Every admitted member of that group must carry the same anchor and compatible structural metadata.

Consider a group anchored at data index 96. With a validated source count of 32, its intended data range is 96 through 127. A batch's trailing group may be shorter, so implementations must follow sanitized declarations instead of assuming a target-sized matrix.

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 that declaration arrives, it can bucket data under the slot and recovery anchor without allocating an unbounded shard array.

Parent offset: linking slot ancestry

A data header encodes parent distance in two bytes. Subtracting it from the current slot yields the claimed parent. Distance one points to the prior slot; greater values cross skipped coordinates.

The representation is a distance because the parent is always earlier. Validation rejects zero, underflow, and values that cannot produce an admissible parent. Every data member admitted for one slot should report a consistent 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 data-header byte combines a six-bit reference tick with two high-bit completion signals. DATA_COMPLETE ends one serialized batch of entries. LAST_IN_SLOT identifies the slot's terminal data packet; its semantics include completion too.

That distinction matters because several batches may finish before a slot's final shred. Consumers can deserialize each closed prefix without waiting for the slot-ending signal. This incremental boundary is one source of direct shred consumption's latency advantage.

Flag combinations require validation. A last-in-slot indication without data completion is not valid under the current definition. Reference tick helps placement and sanity checking, yet cannot serve as wall-clock time or replace receive timestamps and full Proof of History verification.

Size: the meaningful data boundary

On a data shred, the two-byte size value bounds its meaningful serialized region relative to packet layout. This keeps padding and trailing authentication material out of 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. Combined with enough independent peers, parity position seven contributes to recovery at any absent source position. Naming the field recovery target in application code usually predicts a later mapping bug.

Coding index and parity position serve different protocol functions. The first orders coding packets across their slot; the second locates an erasure row within one recovery group. Store both, check their relationship, and use the parity coordinate to assemble the Reed-Solomon 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. Packets sharing a slot and recovery anchor must agree on dimensions, variant family, Merkle root, and other group-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.

Scope of this page

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

Every current shred carries six common values. Their widths are 64 bytes for the signature, one for variant, eight for slot, four for index, two for shred version, and four for the FEC anchor. Together they occupy 83 bytes. The type-specific header that follows differs for data and coding packets.

DATA_COMPLETE identifies the packet ending one serialized entry batch. Once gaps are filled, a receiver can concatenate the consecutive data range through that index and decode it. The slot may continue afterward. LAST_IN_SLOT separately identifies its terminal data packet, with completion included in that signal's meaning.

No. Within its type's slot-wide sequence, a shred index names one packet. The FEC value instead names the data-index anchor where a recovery group begins, so many members repeat it. Receivers form identity from type and index within a slot, while FEC state uses the slot plus that anchor.

Common index places a coding packet in its slot-wide type sequence. Coding position instead selects a parity row within one recovery group, with valid values below the declared coding count. Reed-Solomon assembly consumes that position. Deduplication and storage identify it by slot, type, and common index together.

No. Slot denotes a consensus and leader-schedule coordinate rather than wall-clock time. 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.