Troubleshooting
Symptoms, likely causes, and verification steps. For problems not listed here, see Exit codes for the error code key and FAQ for design-rationale questions.
"No space left on device"
The extraction filled the output filesystem. Two causes:
-
The extracted tree is genuinely bigger than the free space. Check the archive's expected uncompressed size (most formats report it in their metadata, and
peellogs it on the progress UI's first line). If that exceeds free space, more disk is required: the sliding window only bounds the compressed side. -
The part-file's lookahead window grew faster than the decoder consumed it. Lower
--max-disk-buffer(default 1 GiB) so the scheduler back-pressures sooner:peel <URL> --max-disk-buffer 128MiB -o ./out/Then confirm hole-punching is working (see the next section).
"Hole-punching seems disabled / part-file is huge"
Check the part-file's physical size (du -h) versus its
logical size (ls -la):
$ ls -la out.peel.part out.peel.ckpt
-rw-r--r-- ... 10737418240 ... out.peel.part # 10 GiB logical
$ du -h out.peel.part
182M out.peel.part # 182 MiB physical (healthy)
If du is close to ls, hole-punching is not trimming. Possible
causes:
-
-k/--keep-archiveis set. The puncher is intentionally disabled. Remove-kif archive preservation is not required. -
--no-extractis set. Nothing decodes, so nothing punches. Expected for--no-extract: the bytes are kept verbatim. -
The filesystem does not support punch-hole. Some unusual mounts and old kernels reject it.
peellogs awarn!at startup when the probe fails:WARN filesystem rejected MADV_REMOVE probe, falling back to fallocate(PUNCH_HOLE) WARN filesystem rejected fallocate(PUNCH_HOLE) probe, source bytes will not be releasedMove the workdir to a filesystem that supports it (
--workdir /var/tmp/peel), or accept the larger transient footprint.
"io_uring fallback warning"
On Linux, one of these messages may appear:
WARN io_uring_setup failed (errno=1 EPERM), falling back to blocking sockets
WARN io_uring not available (kernel < 5.6), falling back to blocking sockets
WARN RLIMIT_MEMLOCK too low for io_uring (need at least N KiB), falling back to blocking sockets
These are informational, not errors. peel falls back to the
blocking backend and continues. The fallback path is the same code
every non-Linux build uses; results are correct either way.
To force io_uring and fail-fast when it is not available:
peel <URL> --io-backend uring -o ./out/
Common causes:
- Seccomp profile blocks the syscalls.
cri-o's default profile is the most common case under Kubernetes. Addio_uring_*to the allowed syscalls or accept the fallback. - Kernel too old. Minimum 5.6 for the SQEs
peeluses. In practice 5.10+ is more reliable. RLIMIT_MEMLOCKtoo low. Container default may be 16 KiB, whileio_uringrings need a few MiB. Raise the limit (ulimit -l unlimitedin the container spec) or accept the fallback.
"Wrong digest at completion"
error: digest mismatch
expected: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
got: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
The streamed bytes did not hash to the value asserted by --sha256.
Possibilities:
- The source moved or was re-uploaded. Re-download a small
sample (
curl --range 0-1023 $URL | sha256sum) and compare against what the publisher currently advertises. - Wrong hash supplied. Double-check the hash source.
- A
--mirroris serving subtly different bytes. Remove mirrors one at a time to identify the culprit.peeldrops misbehaving mirrors at the HEAD validation step, but some forms of subtle corruption only show up post-decoder.
"Source changed during run"
error: source changed during run
chunk 1247 fingerprint mismatch: stored=…, refetched=…
The CRC32C fingerprint of a chunk does not agree across fetches. The source bytes changed between when one worker fetched the chunk and when another did. Causes:
- CDN-edge cache drift. Common with mirror infrastructure that is mid-rollout. Wait for propagation, then re-run.
- Origin re-uploaded the file. Check the upstream publishing timeline.
- Network corruption. Rare with TLS, but observed on some middlebox-heavy paths. Repeat the run; the second attempt usually succeeds.
Delete the .peel.ckpt to start fresh from the part-file's bytes
(which peel re-verifies chunk-by-chunk), or delete both sidecars
to start completely from scratch.
"ETag mismatch on resume"
error: source identity changed since last run
ETag at startup: "8b1a9953c4611296a827abf8c47804d7"
ETag now: "65a8e27d8879283831b664bd8b7f0ad4"
The source's ETag (or Last-Modified) changed between the start of
the run and the resume. peel aborts rather than silently mixing
bytes from two different versions of the file.
Two fixes:
- Delete the sidecars and start from scratch. The bytes already on disk belong to the previous version and are not useful.
- Pass
--sha256of the new version. With--sha256set, the hash is the source of truth, and agreeing mirrors are trusted regardless of ETag drift.
"Multi-volume probe returned 404s"
warn: multi-volume probe: backup.part0005.rar returned 404, stopping at 4 volumes
This is normal: auto-discovery stops at the first missing
volume. The reported count is what peel will fetch.
If more volumes are expected than the probe found:
- The volumes may be on a different host or path.
- The numbering may have a gap.
- The volumes may use a different convention than the seed implies.
Use the explicit positional list or an @manifest.txt file instead.
"Wrong format detected"
error: format mismatch: URL suffix says .tar.zst, magic bytes are 0x1f 0x8b (gzip)
pass --force-format-from-magic to trust magic, or --format <NAME> to pin
The URL suffix and the magic bytes disagree. Three options:
- Trust the magic when the file is known to match its bytes:
--force-format-from-magic. - Pin the decoder when the expected format is known:
--format zstd(or whichever). - Investigate the source. The file may have been re-encoded without renaming, or the URL is genuinely serving the wrong file.
"Permission denied" writing the output
The output's parent directory is not writable for the user running
peel. The error message names the path:
error: cannot create output directory ./out/: Permission denied (os error 13)
peel does not elevate privileges. Run as a user with write
permission on the output path, or use --workdir to relocate only
the sidecars to a writable location while writing the final
extracted tree to a location the user owns.
"Output file already exists" (or seems to)
peel overwrites the extracted output:
- For tree-shaped outputs (tar, zip, 7z, rar), existing files at paths matching an archive entry are overwritten. Existing files at paths not in the archive are left alone.
- For stream-shaped outputs (raw
.zst,.xz,.lz4,.gz), the output file is overwritten unconditionally.
For a non-destructive run, point -o at a fresh directory.
"I want to interrupt and resume later"
Press Ctrl-C (or send SIGTERM). peel traps the signal, flushes
the in-flight checkpoint, and exits with code 130 (SIGINT) or 143
(SIGTERM). The sidecars stay on disk. Re-run the exact same command
to resume.
kill -9 (SIGKILL) is also safe. peel is designed so that even
an ungraceful kill leaves the part-file's bytes and the last
checkpoint in a consistent state, and the next run reconciles.
"Where do the logs go?"
stderr. The progress UI block goes to stderr as well, redrawn in
place on a TTY. To capture:
peel <URL> -o ./out/ 2>peel.log # only log
peel <URL> -o ./out/ 2> >(tee peel.log >&2) # log and show
RUST_LOG=debug peel <URL> -o ./out/ 2>peel.log # verbose
"Live progress UI shows wrong percentage"
The percentage is streamed_bytes / Content-Length. Two pitfalls:
- For multi-part URLs, the denominator is
the sum of all parts'
Content-Lengthvalues (accurate). - For a server that does not return
Content-Length(rare, mostly badly-configured proxies),peelfalls back to a chunk-count progress estimate. The percentage will be approximate.
Getting better diagnostics
Always run with RUST_LOG=info (or RUST_LOG=debug) when filing a
bug report:
RUST_LOG=debug peel <URL> -o ./out/ 2>peel-debug.log
The first few lines list the selected backends, the discovered volumes and mirrors, and the format detection result. Misbehaviour typically shows up there.