Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Fault Reference

Every fault the simulator can inject, with where it is configured and how it shows up. Rates and defaults are in the Configuration Reference. Every fault is drawn from the one seeded stream, so it replays exactly.

Network Faults

Enabled by Chaos::Network(mode), limited by network_fault_mask. Each family is one NetworkFault bit.

NetworkFaultBitWhat happensConfig fields
Clog1 << 0One IP’s sends, receives or both are held for a duration, then resume. Arrivals are a rate per simulated second.clog_rate, clog_duration
Partition1 << 1Directed partitions. Sends between the chosen IPs are stalled until healed. Arrivals are a rate per simulated second, one partition at a time.partition_rate, partition_duration, partition_strategy
BitFlip1 << 21 to 32 bits of in-flight data are flipped.bit_flip_probability, bit_flip_min_bits, bit_flip_max_bits, bit_flip_cooldown
RandomClose1 << 3A connection closes during I/O. A share is an explicit close, the rest a reset.random_close_probability, random_close_cooldown, random_close_explicit_ratio
ConnectFailure1 << 4connect fails or hangs.connect_failure_mode, connect_failure_probability
ClockDrift1 << 5Each node’s clock drifts up to a bound.clock_drift_enabled, clock_drift_max
BuggifiedDelay1 << 6Timers fire late by an extra random delay.buggified_delay_enabled, buggified_delay_max, buggified_delay_probability
PairLatency1 << 7One IP pair gets permanent extra latency.max_pair_latency
BlackHole1 << 8A connection whose sends vanish silently and forever.black_hole_probability, black_hole_cooldown

Partial reads and writes (partial_write_max_bytes, partial_read_max_bytes) are TCP behaviour exercised through buggify. The mask does not touch them.

PartitionStrategy picks the victims: Random, UniformSize, IsolateSingle, IsolateZone, IsolateDatacenter, AsymmetricSend, AsymmetricRecv. The locality strategies need cluster(..) topology.

NetworkFaultMask::all(), none(), .with(fault), .without(fault), .contains(fault). Recovery mode (SimWorld::enter_recovery_mode) is the none() mask plus healing of held partitions.

Manual network control

MethodOnEffect
partition_pair(from, to, duration)SimWorldDrop sends from from to to for duration.
partition_send_from(ip, duration)SimWorldDrop every send from ip.
partition_recv_to(ip, duration)SimWorldDrop every send to ip.
restore_partition(from, to)SimWorldHeal one direction.
is_partitioned(from, to)SimWorldQuery.
partition(a, b), heal_partition(a, b), is_partitioned(a, b)FaultContextThe same, by IP string, from a custom injector.

Storage Faults

Enabled by Chaos::Storage(mode), limited by storage_fault_mask. Fault coordinates are a file path plus a flat 512-byte sector offset.

StorageFaultWhat happensConfig fieldsReported as
CorruptionA read or write plants a latent, deterministic sector corruption.read_corruption_probability, write_corruption_probabilityStorageFaultKind::ReadCorruption, WriteCorruption
EioA read or write fails with an I/O error. The bytes are not corrupt.read_eio_probability, write_eio_probabilityEioRead, EioWrite
MisdirectA read is served from, or a write lands at, the wrong offset.misdirect_read_probability, misdirect_write_probabilityMisdirectedRead, MisdirectedWrite
PhantomWriteA write reports success and never reaches the disk.phantom_write_probabilityPhantomWrite
SyncFailuresync_all, sync_data or sync_dir fails.sync_failure_probabilitySyncFailure
ShortTransferA read or write transfers fewer bytes than asked.short_transfer_probability
DirEntryLossA crash loses a directory entry that was not sync_dir’d.unsynced_dir_entry_loss_probabilityDirEntryLost
CrashDamageUnsynced sectors resolve by crash physics (below).crash_lost_probability, crash_latent_fault_probability, shorn_write_probabilityFileCrashReport
DegradationDisk stall (operations wait) or throttle (iops and bandwidth divided) episodes.disk_stall_*, disk_throttle_*
DiskFailureThe disk fails for good. Every later operation stays pending forever.disk_failure_probabilitystorage_disk_failure event
DroppedMutationDiscardA write, sync or set_len whose future was dropped is discarded instead of landing. Without it, every dropped mutation lands at its scheduled time.dropped_mutation_discard_probability
WritebackErrorAfter a write, the background writeback fails (fsyncgate). The dirty sectors become clean but not durable, so a retried sync succeeds and a crash can still lose them. writeback_error_reporting picks which handles see the error.writeback_error_probability, writeback_error_revert_probability, writeback_error_reportingWritebackError, storage_write_fault with write_kind = "writeback"

The barrier-violation family (barrier_violation_probability) is separate from the mask. When it is 0, a sector a sync reported durable that changes across a crash fails the run with StorageFaultKind::LostSyncedWrite. This is the lost-synced-write oracle. When it is above 0, the lie is permitted and recorded.

StorageFaultMask::all(), none(), .with(fault), .without(fault), .contains(fault). StorageConfiguration::disable_fault_injection() zeroes every family including barrier violation.

The crash model

A crash (any RebootKind::Crash, CrashAndWipe, crash_self, or a disk crash during simulate_crash_for_process) resolves every sector written since the last sync independently:

CrashOutcomeMeaning
KeptOldThe sector holds the bytes before the write.
KeptNewThe write survived.
LostThe sector holds the fill pattern (garbage_fill_probability chooses garbage over zeros).
LatentFaultThe sector reads back with an error until rewritten.
ShornPart of the sector is old, part new.

clean_crash_probability makes some crashes lose nothing. correlated_rollback_probability and correlated_rollback_max_run roll back a run of adjacent sectors together. length_survives_crash_probability decides whether an unsynced set_len survives. FileCrashReport lists the outcome per sector; SimWorld::take_storage_crash_reports() drains them.

Targeted injection

MethodOnEffect
corrupt_file(path, sectors)SimWorldCorrupt sectors of a file now.
fail_file_with_eio(path, sectors, EioTarget)SimWorldMake reads, writes or both fail on those sectors.
clear_file_eio(path, EioTarget)SimWorldLift it.
corrupt_durable_out_of_band(path, sector)SimWorldCorrupt a synced sector without a crash (bit rot).
corrupt_process_file_bytes(ip, path, bytes)SimWorldOwner-scoped byte range corruption.
fail_process_file_with_eio(ip, path, sectors, EioTarget), clear_process_file_eioSimWorldOwner-scoped EIO.
process_file_durable_bytes(ip, path)SimWorldThe durable image of a file.
durable_bytes(ip, path), corrupt_bytes(..), fail_file_with_eio(..), clear_file_eio(..)FaultContextThe same from a custom injector.
simulate_crash_for_process(ip, close_files)SimWorldRun crash resolution on a process’s files.
wipe_storage_for_process(ip)SimWorldDelete every file the process owns.
fail_disk_for_process(ip)SimWorldPermanent disk failure. is_disk_failed(ip) queries.
set_disk_capacity(ip, Option<DiskCapacity>), disk_capacity(ip), disk_space(ip)SimWorld, FaultContextA disk size limit: growth past it fails with ENOSPC (StorageFaultKind::DiskFull, a storage_write_fault with write_kind = "full"). Recovery mode lifts it.
set_storage_eligibility_mask(mask), clear_storage_eligibility_mask()SimWorldGate the random families by (path, sector).
set_fault_focus(focus), clear_fault_focus(), publish_layout(..)SimWorldWeight the random families by byte range or LayoutRegion.
draw_replicated_faults(config, localities)SimWorldDraw a FaultPattern for a replicated group.
take_storage_fault_records()SimWorldDrain StorageFaultRecord { path, kind, .. } entries.

EioTarget is Read, Write or ReadWrite.

Replicated fault patterns

replicated_storage_faults(ReplicatedFaults::new(DomainLevel::Machine).tolerance(1).group("acceptors")) bounds damage so that a correct replication layer can always repair:

FaultPatternDamage
Minority { domains }Only the listed domains, at most tolerance.
Striped { domains, local }Stripe s may be damaged in the s mod n-th domain; the local domains anywhere.
Rolling { domains }A window of tolerance domains at a time. The window moves once the damage is repaired.
SparedFewer than two domains: nothing is damaged.

The stripe key comes from LayoutRegion::stripe (the journal uses the entry position), so one pattern hits the same position on every replica.

Process Faults

FaultSourceWhat happens
Graceful rebootAttrition (prob_graceful), FaultContext::reboot(ip, RebootKind::Graceful)The shutdown token is cancelled. After the grace period the process is force killed, then restarted after the recovery delay.
Crashprob_crash, RebootKind::Crash, FaultContext::crash(ip)Tasks aborted, connections reset, storage through crash resolution.
Crash and wipeprob_wipe, RebootKind::CrashAndWipeCrash plus deletion of every owned file.
Timed crashFaultContext::crash_for(ip, down)Crash, restart after down.
RestartFaultContext::restart(ip)Restart a process that crash left down.
Random victimFaultContext::reboot_random(kind), reboot_tagged(..)One random eligible process.
Domain rebootFaultContext::reboot_machine(..), reboot_domain(..); AttritionScope::{PerMachine, PerZone, PerDatacenter}Every process of the domain at once.
Self crashSimContext::crash_self(kind, Option<Duration>), SimContext::self_crash() -> SelfCrashA process kills itself one scheduler tick from now, at an exact point of its protocol. No randomness is drawn. Only a process may call it.
OutageChaos::OutageEvery process of the named groups loses power at one instant. A workload can hold it with OutageVeto.
Hinthint!("label") in library codeThe seed’s first admitting attrition regime may reboot the process at that moment. A workload can budget it with HintVeto::new(|ip, label| bool).publish(state) under HINT_VETO_KEY. The veto also guards a per-process regime’s timed reboots, asked with TIMED_REBOOT_LABEL.

Reboots are bounded by max_dead per injector pool. The restart runs the process factory again: a fresh instance, the same IP, the same disk unless wiped.

CPU and Gray Failures

FaultSourceWhat happens
CPU timeChaos::Cpu(mode), SimWorld::set_cpu_modelEvery poll, sent byte and written byte costs simulated time on the process’s one core. cpu_charge(Duration) adds explicit work.
Gray failureChaos::GrayFailure { config, mode }Up to max_slow machines run slow for a long window: CPU, disk and network multipliers.
Manual slownessFaultContext::set_slowness(ip, Slowness), SimWorld::set_slownessInstall multipliers by hand. SimContext::slowness(ip) reads them.

Buggify Knob Spikes

Chaos::BuggifyKnobs calls apply_buggify_knobs() on the enabled network and storage profiles for some seeds, the way FoundationDB randomizes knobs under BUGGIFY. It has no effect on a surface that is off.

SurfaceKnobSpiked range
Networkclog_rate2 to 5 per second (only when the seed has clogs)
Networkpartition_rate0.5 to 2 per second (only when the seed has partitions)
Networkrandom_close_probability0.01 to 0.1
Networkblack_hole_probability0.01 to 0.1
Networkbit_flip_probability (if already on)0.001 to 0.01
Storageiops100 to 5000
Storagebandwidth1 MB/s to 20 MB/s
Storagesync_failure_probability0.05 to 0.2
Storagedisk_stall_probability, disk_stall_duration0.1 to 0.5, 100 ms to 500 ms
Storagedisk_throttle_probability, disk_throttle_duration0.1 to 0.5, 1 s to 5 s
Storagedisk_failure_probability0.001 to 0.01

Fault Events in the Timeline

The engine records SimFaultEvents. The runner merges them into the trace under SIM_FAULT_EVENT_NAME ("sim_fault") with source = "sim" and a kind field. An invariant queries them with q.since("sim_fault", &cursor).

kindFamily
process_graceful_shutdown, process_force_kill, process_restartprocess lifecycle
partition_created, partition_healeddirected partitions
send_partition_created, send_partition_healed, recv_partition_created, recv_partition_healedone-sided partitions
interface_cloggedclogs
random_close, black_hole, bit_flipconnection faults
storage_read_fault, storage_write_fault, storage_sync_faultstorage I/O faults
storage_disk_failure, storage_crash, storage_wipedisk and crash

SimWorld::take_faults() drains them in a low-level test.

Presets

PresetUse
NetworkConfiguration::default()FoundationDB’s always-on rates: rare random closes, clock drift, buggified delays, probabilistic connect failures. No clogs, partitions, bit flips or black holes.
NetworkConfiguration::fast_local()Microsecond latencies, chaos disabled.
ChaosConfiguration::disabled()Every network fault off.
StorageConfiguration::default()Realistic SSD timing, no faults.
StorageConfiguration::fast_local()1 µs operations, no faults.
random_for_seed() / swarm_for_seed()What ChaosMode::Random and ChaosMode::Swarm draw.