Environment Variable Reference¶
Docs-site note (rewritten 2026-07-11): This page is grounded directly in source — the binary's own baked-default table and the per-flag
getenvcall sites that consume each variable — not in intent or naming. Where a flag's default changed since this page was first written (2026-06-25), that's because the binary itself changed: most of what used to be a manual deploy-script flag list is now filled in automatically. For the build-time (-D) side of the picture, see the Build-Flag Reference; for how these runtime variables reach the validator process during a deploy, see Deploying Vexor.
The short version¶
Vexor now bakes its own production defaults. The very first thing the binary does at startup — before any
subsystem reads an environment variable — is fill in 23 VEX_* variables to their proven values, but
only if you haven't already set them. An explicit value on your deploy command line always wins over the bake.
That means the honest, current operator surface is small: a handful of machine-specific variables (which binary, which cores, whether AF_XDP is available on this NIC) plus your keys and network address. Everything that used to be a long "remember all these flags" recipe is now a property of the binary itself. See the minimal recipe on the Build-Flag Reference page.
Two guards keep the bake safe:
- Production-only. The bake is skipped entirely when the binary detects an offline-replay or golden-gate
context (
VEX_LEDGER_REPLAYorVEX_SNAPSHOT_OFFLINEset). Those runs deliberately want the ledger write path, the watchdog's restart authority, and leader broadcast to stay off — baking them on would be actively wrong for a read-only replay. - Machine facts are never baked. A fixed set of variables — which binary to run, hardware/NIC capability, core lists, snapshot freshness policy — legitimately differ from host to host and are deliberately left for the operator to set. See the minimal operator surface below.
Value-parse semantics¶
Most of the flags on this page follow one contract: unset means "let the binary decide" (baked default if
there is one, otherwise off); an explicit 0 or false means "off, and this overrides the bake"; any
other value — including the conventional 1 — means "on."
A few flags parse more strictly and only accept an exact "1" (or, on one flag, an exact "0") to arm or disarm;
"true" / "yes" will not arm them. If you want a value that's guaranteed to work everywhere on this page, use
1 to turn something on and 0 to turn it off — both are accepted by every flag here, strict or not.
The baked necessity set¶
These 23 variables are set to the value below automatically at startup if you don't set them yourself. You do
not need to put any of these in a deploy command for a standard testnet voting deploy — they're listed here so you
know what a "default" boot is actually doing, and so you can force one off (=0) for a specific diagnostic
session without a rebuild.
| Variable | Baked value | What it actually does |
|---|---|---|
VEX_LEDGER |
1 |
Initializes the persistent VexLedger blockstore and spawns its write tile. See VexLedger. |
VEX_DAG_DISPATCH |
1 |
Enables the single-threaded conflict-DAG dispatcher on the replay path — the live transaction-ordering mechanism. |
VEX_PARALLEL_EXEC |
1 |
Arms wave-barrier parallel transaction execution inside the DAG dispatcher (requires VEX_DAG_DISPATCH, also baked on). |
VEXOR_ED25519_FEC_DEDUP |
1 |
Arms the Ed25519 FEC-set signature-dedup cache in the verify tile. |
VEX_DISABLE_NETHASH |
1 |
Despite the name, this value turns a liveness band-aid off: the node votes its own locally computed bank hash rather than falling back to a cluster-reported one. |
VEX_LEADER_BROADCAST |
1 |
Enables real leader-slot block broadcast instead of loopback-only. On its own this only ever produces empty, cluster-accepted blocks — it cannot make a block transaction-bearing by itself (see experimental flags below). |
VEX_TURBINE_REAL_STAKES |
1 |
Builds the turbine broadcast/retransmit tree from real epoch stake weights instead of a uniform stub (falls back to uniform, with a warning, if epoch stakes aren't populated yet). |
VEX_STAKE_BPF |
1 |
Routes stake-program instructions through the on-chain SBPF VM path instead of a native Zig implementation — the canonical path for testnet. |
VEX_FORK_ISOLATION |
1 |
Enables per-fork account-state isolation during replay. Strict parse: only an exact "1" arms it. |
VEX_REPAIR_INFLIGHT |
1 |
Arms in-flight repair-request tracking, so the same shred isn't re-requested while a request is already outstanding. |
VEX_CATCHUP_ADAPTIVE_REFIRE |
1 |
Arms adaptive repair re-fire behavior during catch-up. |
VEX_VOTE_REFRESH |
1 |
Re-sends the byte-identical last vote on a fresh blockhash if the node stalls without casting a new one — never a new vote, so it can't be a slashing risk by construction. |
VEX_SWITCH_PROOF |
1 |
Arms (not shadow-only) the cross-fork switch-threshold proof that authorizes voting a different fork than the node's current one, on top of — never instead of — the lockout check. |
VEX_PROP_GATE |
1 |
Refuses to vote a fork whose propagation hasn't been confirmed, when armed. |
VEX_PROP_LATCH |
1 |
Selects canonical leader-window propagation-latch target selection for vote targeting. |
VEX_CANONICAL_VOTE |
1 |
Arms canonical heaviest/canonical-leaf vote selection, the counterpart to VEX_SWITCH_PROOF above — the two are meant to run together. Added to the baked set after shipping separately (switch-proof armed, canonical selection unbaked) was traced to a recurring switch-proof stall. |
VEX_VOTE_PREWARM |
1 |
Arms targeted QUIC connect-ahead for validators the node expects to need shortly, in the vote poller. |
VEX_DISABLE_CURL_VOTES |
1 |
Forces the legacy curl/UDP vote-relay path off. Belt-and-suspenders: that path is already opt-in, so this mostly guards against it being turned on by accident. |
VEX_REPAIR_SKIP_ABANDONED |
1 |
Only takes effect when a cluster oracle also confirms a slot is genuinely abandoned — it is not a blind repair skip. |
VEX_WATCHDOG_RESTART |
1 |
Lets the liveness watchdog restart the process on a sustained wedge, instead of alert-only. |
VEX_LEDGER_MAX_BYTES |
107374182400 (100 GiB) |
Bounds on-disk ledger size; prunes the oldest whole segments once the cap is hit. |
VEX_LEDGER_KEEP_SLOTS |
216000 |
Alternate ledger-prune policy (keep the last N slots); the byte cap above takes precedence if both are set. |
VEX_VOTE_FANOUT_ROTATIONS |
3 |
Number of fanout rotations used when broadcasting a vote. |
The minimal operator surface¶
These are the variables that legitimately vary per host and are never filled in automatically. Everything else that's genuinely load-bearing for a standard deploy is above.
| Variable | Purpose |
|---|---|
VEX_BINARY |
Which pre-built binary to run. |
VEX_ALLOW_NO_BN254 |
Required (=1) for a -Dpure_zig binary. The BN254 boot guard historically assumed a linked Firedancer Ballet BN254 library and refuses to boot without one; a pure-Zig binary has no such library by design (BN254/Poseidon run through Vexor's own vex_crypto instead), so this variable tells the guard that is expected. Not needed for a Ballet-backed (non--Dpure_zig) binary. See Building Vexor. |
VEX_ENABLE_AFXDP |
Enables AF_XDP zero-copy networking on NICs that support it. Note: the transport switch itself comes from the corresponding CLI flags your deploy wrapper derives from this variable; the variable's own direct effect in the binary is narrower — a dedicated allocator arena for the receive thread and occupancy instrumentation. Set it wherever your deploy tooling expects it. |
VEX_FRESH_SNAPSHOT |
1 (recommended default) re-extracts the snapshot every boot and, if the local tarball is more than VEX_SNAP_MAX_AGE_SLOTS behind the live tip, downloads a fresh near-tip base+incremental pair. Working account cache, ledger, and tower state are wiped either way — this is the production-correct path, since it never inherits possibly-corrupt local state. |
VEX_SNAP_MAX_AGE_SLOTS |
Freshness threshold for the check above, in slots. 0 forces a refetch on every boot; a very large value effectively preserves whatever local snapshot is already there. |
VEX_REUSE_SNAPSHOT |
1 boots from the existing local extracted-* snapshot without deleting or re-downloading it — the safe way to reproduce a specific slot for carrier diagnosis or regression repro. Working account cache, ledger, and tower are still wiped and rebuilt from that snapshot. Default 0 (off; use VEX_FRESH_SNAPSHOT behavior instead). |
VEX_PARALLEL_EXEC_CORES |
Which CPU cores host the parallel-execution worker pool. Hardware-specific — see Hardware. |
VEX_TASKSET_CORES |
The process-wide CPU affinity mask. Hardware-specific. |
VEX_UMEM_RESERVE |
AF_XDP UMEM frame reservation count. |
Identity keypair, vote keypair, public IP, ports, cluster entrypoints, and data-directory paths are CLI arguments, not environment variables — see the Build-Flag Reference minimal recipe for an example and your deploy tooling's own flags for the full argument list.
Experimental, keep-gated flags (not production)¶
These compile in and ship in the binary, but are deliberately left off by default and off in the baked-default list — they're real, working code paths that haven't earned a place in the standard deploy yet.
| Variable | What it does | Status |
|---|---|---|
VEX_TPU_INGEST |
Enables transaction ingest into an in-memory mempool, independent of block broadcast. | Not production. Safe on its own (loopback only), but see the interlock below. |
VEX_TXBEARING_BROADCAST |
The interlock that would let a broadcast block actually carry transactions (instead of an empty, cluster-accepted block). | Not production. Combined with VEX_TPU_INGEST and broadcast, transaction-bearing blocks currently diverge from cluster consensus and get skipped. Leave this off; produced blocks stay empty and valid without it. |
VEX_FORCE_INLINE_PRODUCE |
Gated, working code path. | Not production. Confirm the exact effect in source before relying on it — not covered in operator-facing deploy guidance. |
VEX_GOSSIP_PROP |
Gated, working code path. | Not production. Confirm the exact effect in source before relying on it — not covered in operator-facing deploy guidance. |
VEX_BLOCK_DAG |
Gated, working code path. | Not production. Confirm the exact effect in source before relying on it — not covered in operator-facing deploy guidance. |
Diagnostic and forensic flags¶
Everything in this category defaults off, is intended for parity investigations or crash forensics, and has no place in a normal deploy. Rather than list every individual name, here's the shape of what exists, grouped:
| Category | What it's for | Examples |
|---|---|---|
| Account read/write recorder | Per-slot account access tap for parity investigations | VEX_RECORD_READS, VEX_RECORD_WRITES, VEX_RECORD_SLOTS |
| State/field dumps | Dump bank or account state at a given point | VEX_FREEZE_DUMP_SLOT, VEX_ACCT_DUMP, VEX_DUMP_ENTRY |
| Lt-hash verification | Verify or trace the accounts lt-hash | VEX_VERIFY_LTHASH_SLOT, VEX_VERIFY_LTHASH_WRITES, VEX_LT_DELTA |
| Vote / gossip probes | Byte-level vote and gossip transport diagnostics | VEX_VOTE_PROBE, VEX_PROBE_SYSVAR_BYTES, VEX_PROBE_IDENTITY |
| SBPF VM debug | BPF interpreter tracing | VEX_CALLX_DEBUG, VEX_VMFAULT_DEBUG, VEX_BPF_DBG_PROBES |
| KAT / fixture replay | Known-answer-test harness inputs | VEX_KAT_HASH, VEX_FIXTURE_ONLY |
| Allocator debug | Swap in Zig's checked debug allocator to catch use-after-free with a real stack trace | VEX_DEBUG_ALLOC — slow, boot only to hunt a crash, never for production |
If you're chasing a specific consensus or performance question and think one of these is relevant, it's worth confirming the exact call site in source before relying on it — some historical variable names in older deploy notes turn out to have no live effect in the current binary.
Metrics — SOLANA_METRICS_CONFIG¶
Vexor reports metrics using the same environment variable and format as Agave:
If the variable is unset or fails to parse, the metrics reporter logs that it's disabled and the validator runs normally — there's no metrics-config requirement to vote. For the public testnet metrics write endpoint and credentials, see Anza's cluster documentation rather than copying a value from anywhere else — those are the canonical, current values for the cluster you're joining.
VEX_MODE (planned)¶
A single VEX_MODE switch is planned to select the validator's role in one step, replacing the current mix of
individual flags for the same decision:
| Value | Role |
|---|---|
full (planned default) |
Vote and produce blocks — today's behavior. |
vote |
Vote only; never produce or broadcast blocks. |
rpc |
Follow the cluster only — no voting, no block production. |
This has not shipped yet. It's designed as a thin macro over the existing VEX_LEADER_BROADCAST flag plus one
new voting-enable gate, specifically so that full mode remains byte-identical to current behavior. Once it
lands, this page will be updated with the shipped specifics; until then, the baked necessity
set above reflects the only mode that exists today (full: vote + produce empty,
cluster-accepted blocks).
Status¶
This page reflects the binary's own baked-default table and the source getenv sites that consume each
variable, audited directly against source rather than inferred from deploy-script history or variable names. If a
flag you're relying on isn't listed here, treat it as unproven for production use until you've confirmed its
effect in source. See Deploying Vexor for the ordered contract these variables are consumed by, and
Building Vexor for the -D build flags a handful of them arm at runtime.