Skip to content

Error Correction (.aerocorrect) ​

AeroVault's v4 wrapper-stack configuration (v3 plus error correction) adds error correction over the encrypted data. The container still uses AEROVAULT3 magic and internal version 3; v4 here names the recovery configuration rather than a new container magic. Recovery can be embedded or stored in a detached, par2-style .aerocorrect sidecar that can repair bit rot in any byte stream: a sealed .aerovault container, a synced backup file, or an ordinary standalone file. On cloud backends durability is already redundant; on USB sticks, consumer NAS disks, optical media, and cold-storage archives, a single bad sector is the difference between an encrypted backup surviving and being gone. Error correction closes that gap.

Credit

Error correction is the fourth wrapper in the design contributed by Ehud Kirsh in the AeroFTP COMMUNITY ROADMAP thread (issue #162) and refined in the Error Correction discussion (#276). The unified one-format-for-any-file .aerocorrect design, the placement model, and the overhead levels are his calls.

What .aerocorrect is ​

.aerocorrect is a detached Reed-Solomon parity sidecar for any byte stream. It protects the bytes of the target without embedding anything into it, so the same format repairs .aerovault containers, synced files, or ordinary files. The sidecar is content-addressed: it binds to the SHA-256 of the protected content, not to a path, vault salt, account, or provider identity. Move the file, rename it, copy it to another disk, and the same sidecar still verifies and repairs it.

The magic bytes are AEROCORR. The format is shared byte-for-byte between the AeroFTP application (v4) and the standalone aerovault crate (0.6.8), pinned by a cross-implementation fixture: a sidecar produced by one verifies and repairs with the other for the same file and overhead level.

Where it sits in the wrapper stack ​

Error correction is the last wrapper in the AeroVault pipeline. It runs after encryption, so it protects the ciphertext bytes and never has to decode the format. It adds parity alongside the data rather than transforming it, which is why v3 + error correction = v4: a v3-only reader simply skips the parity it does not understand and still opens the container.

Where error correction sits in the wrapper stack

For encrypted AeroVault containers, parity covers the ciphertext and repair runs before authenticated decryption. AES-256-GCM-SIV detects forged encrypted content; parity alone does not authenticate it. Ordinary standalone or synced files may have no authenticated encryption, so their repair requires an independent trusted SHA-256 anchor to establish authenticity, as described below. Redundancy provides recovery, not trust.

The definitive stage sequence of the full wrapper stack is:

packing
  -> chunking (Gear-CDC, content-defined boundaries)
  -> keyed-BLAKE3 chunk id (dedup key)
  -> compression (zstd, per chunk)
  -> encryption (AES-256-GCM-SIV, per chunk)
  -> cipher hash (BLAKE3-256, pre-decryption integrity)
  -> error correction (Reed-Solomon parity over the cipher blocks)

Compression runs before encryption (ciphertext is incompressible) and after chunking (a single compression stream over the whole input would destroy content-defined chunk boundaries). See The AeroFTP Wrapper Stack for the full reasoning behind the ordering.

Placement: detached, embedded, or both ​

For a vault the parity can live in three places (RecoveryPlacement):

PlacementWhere parity livesEffect on the container
detached (opt-in for vault creation)Sibling .aerocorrect file next to the containerContainer stays byte-identical to a plain v3 vault
embedded (vault-create default; Change Mode when EC is enabled)A non-critical extension inside the container, recomputed on every sealOne self-contained file, parity travels with it
bothSidecar and in-container extensionRedundant recovery surfaces

Example of detached sidecar placement

GUI creation and CLI vault create --error-correction default to embedded placement; CLI creation can select another placement with --recovery-placement. Change Mode explicitly creates embedded parity when Error Correction is enabled for an Archive/v3 target. Detached sidecars remain useful for adding or refreshing parity without rewriting the container, and standalone correct gen creates a detached sidecar. For secret.aerovault, the conventional detached path is secret.aerovault.aerocorrect.

A vault writes exactly three segments (windows) over its container file, in a fixed order, so each region's parity is found by position: a header window, a manifest (locator) window, and a data window. The header and manifest travel outside the container on purpose: a damaged header or manifest cannot self-locate its own recovery (a chicken-and-egg problem), so the sidecar lets the reader rebuild them and prove correctness by the header MAC and the manifest cipher.

For a standalone file or a synced backup there is no three-region structure: the sidecar simply tiles the whole stream into bounded windows and protects each one.

Self-healing (format v2) ​

The .aerocorrect v2 format is self-healing: a lightly-corrupted sidecar still recovers instead of being rejected wholesale.

.aerocorrect v2 sidecar layout

The split is deliberate:

  • The tiny metadata that locates everything (the segment directory, the content hash, and the per-window geometry) is stored in triplicate with per-copy checksums. A single rotted directory copy is detected and the read falls back to a good copy; if no single copy verifies, the locator is reconstructed by byte-majority across the three copies and then validated against the content binding. A reconstruction that does not satisfy the binding is rejected.
  • The bulk parity carries no wholesale checksum. Every Reed-Solomon shard (data and parity) already carries its own checksum, so a rotted parity shard is simply treated as an erasure and routed around at repair time.

This is the key correctness fix over the pre-v2 framing, which used a single all-or-nothing envelope checksum that rejected the entire sidecar on any flip. Self-healing costs about 360 fixed bytes regardless of file size: it does not eat into the main file's parity budget. v1 sidecars are still read; all new sidecars are written as v2.

Overhead levels ​

CLI levels map to storage-overhead targets. The exact Reed-Solomon grid is stored in each payload, so a reader reconstructs from the payload metadata rather than from a CLI-level assumption.

LevelTarget overheadReed-Solomon grid
low~7%approx K=14, P=1
medium~15%approx K=13, P=2
quartile~25%K=8, P=2
high~30%approx K=7, P=2
numeric5-50%clamped into the supported range

Higher overhead survives more damage at the cost of a larger sidecar. medium (~15%) is a sensible default for cold media; raise it for media you expect to degrade.

CLI ​

Standalone files: correct gen | verify | repair ​

The aeroftp-cli correct subcommand protects any file, vault or not:

bash
# Generate a detached recovery sidecar (writes report.bin.aerocorrect)
$ aeroftp-cli correct gen report.bin --ec medium
Wrote report.bin.aerocorrect (31543 bytes, 1 segment(s), 15 shards, 15.5% overhead) for report.bin

# Verify without modifying the file
$ aeroftp-cli correct verify report.bin
Verified: report.bin matches report.bin.aerocorrect

# ...after a 4 KiB run in report.bin is overwritten with zeros...
$ aeroftp-cli correct verify report.bin
Corruption detected in report.bin: run `correct repair` to recover from report.bin.aerocorrect

# Repair in place from the sidecar
$ aeroftp-cli correct repair report.bin
Repaired report.bin from report.bin.aerocorrect (1 shard(s) reconstructed)

Vaults: scrub, repair, and parity management ​

A vault can be created with error correction enabled, scrubbed (verified) on demand, and repaired from whichever parity source is available:

bash
# Create an Error Correction vault at a chosen overhead level
aeroftp-cli vault create secret.aerovault --error-correction --recovery-level medium

# Verify the container against its parity (embedded or sidecar)
aeroftp-cli vault scrub secret.aerovault

# Repair damaged regions; --dry-run reports without writing
aeroftp-cli vault repair secret.aerovault
aeroftp-cli vault repair secret.aerovault --dry-run

# Write or refresh a detached sidecar for an existing vault, without rewriting the container
aeroftp-cli vault export-parity secret.aerovault

# Drop the embedded parity copy (refuses unless a sidecar exists, or --force)
aeroftp-cli vault strip-parity secret.aerovault

export-parity is the add-later win: it reads the encrypted container and writes a sidecar without rewriting the vault, so you can enable recovery on a container that was sealed without it. strip-parity refuses to leave a vault with no recovery at all unless you pass --force. For scrub and repair the parity source resolves in order: an explicit --parity path, then the <vault>.aerocorrect sidecar, then the embedded extension; the chosen source is reported.

Sync: sync --error-correction ​

AeroSync shares the same .aerocorrect sidecar and overhead levels. In v4.2.5, CLI sync --error-correction generates sidecars after successful uploads, subject to the source-size and overhead limits:

bash
# Generate sidecars alongside the synced files
aeroftp-cli sync --profile "Backup" ./local /backup --direction upload --error-correction

# Cap the parity overhead a small file is allowed to add (skips parity below the benefit threshold)
aeroftp-cli sync --profile "Backup" ./local /backup --direction upload --error-correction --ec-max-overhead 25

The CLI text EC summary omits low-benefit skips. They are reported per file on stderr unless quiet mode suppresses the messages, and in the ec_skipped_low_benefit JSON counter. Inspect these outputs before treating a backup as protected.

CLI sync downloads do not automatically verify or repair files from sidecars. The separate desktop sync repair path requires an expected SHA-256 from the scanned item and skips repair if that hash is missing; an S3 MD5 does not satisfy this requirement.

For explicit recovery, download both objects and supply a known-good SHA-256 obtained independently from a trusted source:

bash
aeroftp-cli get --profile "Backup" /backup/report.bin ./report.bin
aeroftp-cli get --profile "Backup" /backup/report.bin.aerocorrect ./report.bin.aerocorrect
aeroftp-cli correct repair ./report.bin --parity ./report.bin.aerocorrect --expect-sha256 YOUR_64_HEX_SHA256

Replace the hash placeholder before running the command. A bare correct repair checks integrity against the sidecar's recorded hash; it does not establish authenticity if an attacker can replace both objects.

Security and repair model ​

Repair is fail-closed and all-or-nothing.

Recovery: file only versus file and sidecar both damaged

  • Re-verify before replace. The rebuilt stream is re-verified against the bound content hash before the original is replaced. For a vault, every reconstructed region is additionally re-verified against the container's authenticated values (the header MAC and the manifest cipher_hash) before being persisted.
  • Use an independent authenticity anchor. Standalone repair without --expect-sha256 trusts the sidecar's declared content hash. Supply a known-good SHA-256 to reject a substituted sidecar before writing. Vault repair additionally checks the container's authenticated values; sidecar checksums alone are not an authenticity proof.
  • Atomic writes. Repair writes to a temporary file and renames it into place, so a crash mid-repair never leaves a half-written original.
  • All-or-nothing for vaults. A vault is re-sealed only if every repaired block re-verifies; otherwise the file is left byte-for-byte untouched.

Bounded memory ​

Generation and repair run in 64 MiB windows and read sidecar parity on demand, so memory is bounded to one window plus that window's parity payload, regardless of file size. The .aerocorrect file is capped at 1 GiB.

Specifications ​

aeroftp.app - Released under the GPL-3.0 License. AeroFTP Reviews