Fix it now
- Drop the file
- Repair runs locally
- Download the result
A WAV is one of the simplest audio containers there is, which is exactly why a two- or four-byte mistake in its header can make a whole recording look dead. The file is a RIFF wrapper: the ASCII tag RIFF, a 4-byte little-endian size, the tag WAVE, then a series of chunks — each a 4-byte name, a 4-byte size, and a body. The two that matter are fmt (note the trailing space), which states the sample rate, channel count and bit depth, and data, which holds the raw PCM samples. If the RIFF size at offset 4 or the data chunk size is wrong — a recorder that crashed before patching them, a transfer that truncated the tail, a file that overran the 32-bit size limit — players trust the broken number and report the file as corrupt while every sample is still sitting there. Drop the .wav above and the tool scans for the real fmt and data markers in your browser, recomputes the sizes from what is actually present, and writes a clean canonical header back around your untouched PCM — with nothing ever leaving your device.
Why a WAV reads as corrupt when the PCM is intact
A canonical WAV opens with a 12-byte prologue — the ASCII tag RIFF, a 32-bit little-endian number that is supposed to equal the whole file size minus 8, and the ASCII tag WAVE — followed by chunks. Each chunk is a 4-byte name, a 4-byte little-endian size, then that many bytes of body. The fmt chunk carries a 16-byte body: a format tag at offset 0 (1 = PCM, 3 = IEEE float, 0xFFFE = WAVE_FORMAT_EXTENSIBLE, 0x11 = IMA ADPCM), then channels (offset 2), sample rate (offset 4), byte rate (offset 8), block align (offset 12) and bits per sample (offset 14). The data chunk is just its 8-byte header followed by the interleaved samples. The whole "map" to hours of audio is those few dozen bytes.
That fragility is the whole problem. A recorder streaming to disk does not know the final length until you press stop, so it writes a placeholder into the RIFF size (offset 4) and the data size — often 0 or 0xFFFFFFFF — and rewrites the real values as the last step when it closes the file. Kill the app, pull the power, yank the card or crash the OS before that final patch, and the PCM is fully written but the sizes still say the file is empty. Players believe the header: Windows Media Player throws 0xC00D36C4, Audacity's libsndfile reports File contains data in an unknown format or refuses it as "not a WAV or AIFF file", and ffmpeg prints Invalid data found when processing input, sometimes after warning RIFF size ... bigger than resulting file size.
Other everyday causes land in the same place. A copy or sync that stopped early truncates the data body so its declared size overshoots the bytes present. A recording that ran past roughly 4 GiB overflows the 32-bit RIFF/data size fields, so the counters wrap and the tail looks unreadable. A stray metadata chunk written before fmt , or a byte-order slip, can push a naive parser off the real chunks. In every one of these the samples are intact — it is the bookkeeping that lies.
How the browser rebuilds RIFF/fmt/data without touching the samples
The repair is a structural header rebuild and it runs as pure TypeScript in your tab. It reads the whole file (a valid WAV needs at least the 44-byte minimum header) and then, instead of trusting the RIFF size at offset 4, it scans for the literal ASCII bytes fmt anywhere in the file. That is the key move: a zeroed, placeholder or overflowed master size cannot stop it, because it never reads that field to find its way. From the fmt body it takes only the four values it genuinely needs — the format tag, the channel count (offset 2), the sample rate (offset 4) and the bits per sample (offset 14). If channels, sample rate or bit depth is zero, it stops honestly with a bad-fmt-params result rather than emit noise.
It then recomputes the two derived fields itself — block align as channels × (bits per sample ÷ 8), and byte rate as sample rate × block align — so a wrong byte rate or block align in the original header is simply discarded and replaced with correct arithmetic. Next it scans forward for the data tag. If the declared data size is larger than the bytes actually present (the truncation case), it keeps everything that remains and marks the result truncated-data; if there is no data header at all, it treats the bytes right after the 16-byte fmt body as PCM and marks it no-data-header. The PCM is then trimmed to a whole number of sample frames so a half-written final frame can't click.
Finally it writes a fresh, canonical 44-byte header: RIFF with a corrected size of 36 + PCM length, WAVE, a clean 16-byte fmt chunk with the recovered format/channels/rate/bits and the recomputed byte rate and block align, then data with the true PCM length, and your samples copied verbatim after byte 44. There is no resampling and no re-encoding — the audio bytes are the exact ones you recorded, so the repair is lossless. The tool reports the sample rate, channel count, bit depth and PCM byte count it recovered, and a damage class of header (a clean success) or truncated-data/no-data-header (a partial). None of it touches the network — you can open the Network tab and confirm 0 bytes of the file are sent.
When it can't rebuild — and what it drops
This repair reaches what survives; it cannot invent a format it can no longer read. It depends on the fmt chunk being present: if fmt is missing or overwritten, the tool stops with a no-fmt result rather than guess, because sample rate, channel count and bit depth cannot be inferred from raw PCM — a wrong guess would play the audio at the wrong speed or as interleaved garbage. Unlike a moov-less video, no healthy reference file is used here, so if the format header is gone, the format is gone. A file under 44 bytes returns too-small, and if trimming to whole frames leaves nothing, it returns no-pcm.
Because it emits a canonical 44-byte header, ancillary chunks are discarded: broadcast metadata (bext/BWF timecode and origination info), cue points (cue ), playlist and label chunks, LIST/INFO tags (artist, comment), the fact chunk, and the WAVE_FORMAT_EXTENSIBLE extension (the cbSize, valid-bits, channel-mask and sub-format GUID). The audio comes back; that metadata does not. The rebuild also assumes constant-size sample frames, so compressed WAV whose block align is not simply channels × bytes-per-sample — IMA/MS ADPCM, GSM 6.10 — will be mis-described by the recomputed block align and may not decode; the tool targets PCM and IEEE float, where that arithmetic is exact.
Two more honest edges. The output is a standard 32-bit RIFF, so PCM beyond about 4 GiB cannot be expressed in the size field — that scale needs RF64/BW64 or Sony Wave64 (.w64), a different container. And samples that a failing drive or card physically overwrote with zeros or silence are not on the disk to recover; pull the raw bytes back at the storage level first, then rebuild the header. What you reliably get back is the intact PCM, correctly described, in a file a player will actually open.
What this can and can't fix
Can fix
- WAVs where a recorder crashed before patching the final RIFF/data size (placeholder 0 or 0xFFFFFFFF) so the file shows as zero-length or corrupt
- A data chunk whose declared size overshoots the bytes present (truncated copy/sync) — keeps every sample that made it to disk
- A wrong or nonsensical byte rate / block align in the fmt chunk — both are recomputed from channels, sample rate and bit depth
- A missing 'data' chunk header — the bytes after the fmt body are treated as PCM and re-wrapped
- A garbage RIFF master size at offset 4 — ignored entirely because the tool scans for the 'fmt ' and 'data' markers instead
- Standard integer PCM and IEEE-float WAVs (mono or multi-channel), rebuilt losslessly with the samples copied byte-for-byte
Can't fix
- Files with no 'fmt ' chunk — sample rate, channels and bit depth can't be guessed from raw PCM, so it stops (reported as 'no-fmt')
- Compressed WAV (IMA/MS ADPCM, GSM) whose block align isn't channels × bytes-per-sample — the recomputed header would mis-describe it
- Broadcast/BWF (bext), cue points, LIST/INFO tags and the EXTENSIBLE fmt extension — dropped when the canonical 44-byte header is written
- PCM larger than ~4 GiB — a 32-bit RIFF size can't hold it; that needs RF64/BW64 or Wave64 (.w64)
- Samples a failing drive or card overwrote with zeros/silence — recover the raw bytes at the storage level first, then rebuild
- A file under 44 bytes, or one where no whole sample frame survives (reported as 'too-small' or 'no-pcm')
If a repair fails, we tell you why (missing data versus broken structure), and you are never charged for a failed repair.