sharkdp/hexyl · error

Failed to jump to the desired input position. This could be…

Error message

Failed to jump to the desired input position. This could be caused by a negative offset that is too large or by an input that is not seek-able (e.g. if the input comes from a pipe).

What it means

After computing the seek target from --skip, reader.seek() fails; b3sum replaces the raw io::Error with this explanation: either the negative offset underflows before the start of input, or the input is not seekable (pipe/stdin).

Solutions

  1. Provide a real file instead of piped stdin when using --skip
  2. Use a non-negative --skip when input comes from a pipe
  3. Reduce the magnitude of negative skips so they stay within the input length
  4. Buffer the input to a temp file first, then skip

Example fix

// before
cat file.bin | b3sum --skip 100
// after
b3sum --skip 100 file.bin
Defensive patterns

Strategy: fallback

Validate before calling

[ -t 0 ] || [ -n "$input_file" ] || { echo '--skip requires a seekable file for positive offsets' >&2; exit 1; }

Type guard

fn is_seekable(f: &File) -> bool { f.seek(SeekFrom::Current(0)).is_ok() }

Try / catch

match result { Err(e) if msg.contains('not seek-able') => buffer_to_temp_file_then_retry(), Err(e) => propagate(e) }

Prevention

When it happens

Trigger: Using --skip with a negative value larger than bytes already read (SeekFrom::End underflow), or using a positive skip when input is stdin/a pipe where seek is unsupported.

Common situations: `cat file | b3sum --skip 100` (pipes are not seekable); `b3sum --skip -999999 file` where the offset precedes file start; reading from process substitution.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.


AI-assisted analysis of sharkdp/hexyl@6ecc29b9c8 (2026-09-09). Data as JSON: /api/errors/ec32c1826cd2bd03. Report an issue: GitHub.

Appendix: source

Thrown at src/main.rs:343

        .map(|s| {
            parse_byte_offset(s, block_size).context(anyhow!(
                "failed to parse `--skip` arg {:?} as byte count",
                s
            ))
        })
        .transpose()?;

    let skip_offset = if let Some(ByteOffset { kind, value }) = skip_arg {
        let value = value.into_inner();
        reader
            .seek(match kind {
                ByteOffsetKind::ForwardFromBeginning | ByteOffsetKind::ForwardFromLastOffset => {
                    SeekFrom::Current(value)
                }
                ByteOffsetKind::BackwardFromEnd => SeekFrom::End(value.checked_neg().unwrap()),
            })
            .map_err(|_| {
                anyhow!(
                    "Failed to jump to the desired input position. \
                     This could be caused by a negative offset that is too large or by \
                     an input that is not seek-able (e.g. if the input comes from a pipe)."
                )
            })?
    } else {
        0
    };

    let parse_byte_count = |s| -> Result<u64> {
        Ok(parse_byte_offset(s, block_size)?
            .assume_forward_offset_from_start()?
            .into())
    };

    let mut reader = if let Some(ref length) = opt.length {
        let length = parse_byte_count(length).context(anyhow!(
            "failed to parse `--length` arg {:?} as byte count",

View on GitHub (pinned to 6ecc29b9c8)