Skip to content

Hydra CLI Guide

Javad Rajabzadeh edited this page Oct 19, 2026 · 1 revision

hya is the command-line half of Hydra. It is the same program as hydra: every install channel puts both names on your PATH, and every example in these pages works with either. The wiki uses hya because it is shorter, and because on a machine that also has THC-Hydra, hydra may be a different tool.

Contents


The shape of a command

hya [OPTIONS] URL...          # download
hya <subcommand> [OPTIONS]    # interactive, checksum, parity, metalink, ...
Subcommand Does
interactive Full-screen download queue
checksum Report the digest a server advertises, without downloading
parity Make or apply Reed-Solomon parity for a file
metalink Read a Metalink document and report what it offers
formats List the file formats Hydra recognises
update Check for a newer release
compat-link Install wget and curl entry points
completions, install-completions Shell completion scripts
plugin Manage resolver plugins

hya --help lists every option. hya <subcommand> --help lists that subcommand's.

Everyday options

hya URL                         # download, saved under the URL's file name
hya -O name.iso URL             # choose the file name
hya -P ~/Downloads URL          # choose the directory
hya -c URL                      # resume a partial file
hya -x 8 URL                    # 8 connections to the server
hya --limit-rate 2M URL         # cap the speed at 2 MB/s
hya -f URL                      # overwrite an existing file without asking
hya --json URL                  # result as JSON on stdout, nothing else

Coming from wget or curl

Hydra reads both dialects, so existing scripts keep working:

hya --compat=wget -c -O file.zip URL
hya --compat=curl -C - -o file.zip URL
hya compat-link --dry-run       # show where the wget/curl links would go

Shell completion

hya install-completions         # writes the script into your shell's completion directory
hya completions zsh > _hya      # or print it: bash, zsh, fish, elvish, powershell

Downloading multiple URLs

Hydra treats several URLs as several files by default. If the URLs are copies of one file, say so with --mirrors.

Several different files

hya https://example.com/a.iso https://example.com/b.zip

They download at the same time, four at once by default. Change that with --parallel-max:

hya --parallel-max 2 URL1 URL2 URL3 URL4

One after another, optionally with a pause between files (a pause implies one-by-one):

hya --mode queue URL1 URL2 URL3
hya --wait 5 URL1 URL2 URL3

A list in a file

One URL per line.

hya --input-file urls.txt

For a queue you can watch and control, see Interactive Queue Manager, which takes the same list with -b urls.txt.

Save into a folder

hya -P ~/Downloads/isos URL1 URL2          # created if missing
hya -y URL1 URL2                           # sort each file into Video, Music, Documents, ...

-y decides the category from the file's contents, not its extension.

Mirrors: several URLs, one file

hya -O ubuntu.iso --mirrors \
  https://mirror-a.example.org/ubuntu.iso \
  https://mirror-b.example.org/ubuntu.iso

Hydra splits the file across all the sources and moves work from slow ones to fast ones as the download runs. Every mirror must report the same size and the same validator; a mirror that disagrees is dropped, and Hydra says why. Mirrors never get mixed in silently.

Metalink

A .meta4 or .metalink document lists the mirrors, the exact size and the expected hash for you.

hya ./Fedora-Workstation.metalink                       # a document on disk
hya "https://mirrors.fedoraproject.org/metalink?repo=fedora-40&arch=x86_64"
hya --metalink https://example.org/big.iso.meta4        # force it when the URL doesn't look like one

Read it without downloading anything:

hya metalink ./Fedora-Workstation.metalink
hya metalink --json https://example.org/big.iso.meta4

Narrow the choice:

hya --metalink-location de,nl,fr ./mirrors.meta4        # prefer mirrors in these countries
hya --metalink-file netinst.iso ./mirrors.meta4         # one entry from a multi-file document
hya --metalink-os linux ./mirrors.meta4

Be gentle to a volunteer mirror

hya --polite URL                 # one connection per host
hya --max-total-connections 8 URL1 URL2

Tips

  • The first URL's file name wins; -O only makes sense for one file.
  • Existing files are never overwritten silently. Use -f to overwrite, --no-clobber to skip, or -c to resume.
  • A failed URL does not stop the others. The summary at the end shows done or failed for each, and the exit code is non-zero if any failed.

Interactive queue manager

hya interactive is a full-screen download manager with a queue. Downloads can be paused and resumed, and the queue survives closing the program.

hya interactive                                          # open the queue
hya interactive URL1 URL2                                # open it with URLs added
hya interactive -b urls.txt                              # add every URL in a file
cat urls.txt | hya interactive -b -                      # read the list from stdin

The URL list file

One URL per line. Blank lines and lines starting with # are skipped.

# ISOs
https://example.com/a.iso
https://example.com/b.iso

# docs
https://example.com/manual.pdf

A line that is not a URL aborts the run before anything is queued, and the error names the line:

hydra: --batch-file urls.txt: not a URL:
  line 3: ubuntu.iso

Options

Option Default Does
-b, --batch-file FILE none Add the URLs in FILE (- for stdin)
-n, --max-active N 2 How many transfers run at once
--queue-file FILE per-user state directory Where the queue is saved
--headless off Work the queue with no screen, one log line per event
hya interactive -n 4 -b urls.txt                         # four at a time
hya interactive --queue-file ./project.queue             # a separate queue per project

Keep going after you close the terminal

Press b in the screen to send the queue to the background. Hydra restarts itself in headless mode in a new session, so transfers continue after the screen closes and after the terminal does.

To start that way directly, for a server or a script:

hya interactive --headless -b urls.txt
nohup hya interactive --headless -b urls.txt > hydra.log 2>&1 &

With no terminal attached (a pipe, cron, CI), hya interactive -b - runs headless on its own:

cat urls.txt | hya interactive -b -

Spider and response headers

Look at a URL without downloading it.

--spider: is it there, and how big is it?

hya --spider https://example.com/big.iso
big.iso  3000000 bytes  ranges=no  validator=Mon, 19 Oct 2026 06:09:52 GMT

You get the file name, the size, whether the server supports byte ranges (this decides whether Hydra can use more than one connection), and the validator. Nothing is saved.

Check a list of URLs:

hya --spider --input-file urls.txt

A bad link fails with a non-zero exit code and a reason, so this works in scripts.

-S: show the exchange

hya -S --spider https://example.com/big.iso
> HEAD /big.iso HTTP/1.1
> Host: example.com
> User-Agent: hydra/...
>
< HTTP/1.1 200 OK
< Content-Length: 3000000
< Last-Modified: ...

> lines are what Hydra sent, < lines are what the server answered. -i and --include mean the same as -S.

Read one header: -H Name

A header name with no value is a question, not a header to send. Hydra prints that header's value and exits:

hya -H Content-Type https://example.com/big.iso
# application/octet-stream

hya -H Content-Length URL
hya -H ETag URL
hya -H Last-Modified URL

Use it in scripts:

size=$(hya -H Content-Length URL)

Sending a header is the same flag with a value:

hya -H 'Authorization: Bearer TOKEN' -H 'Accept: application/json' URL

--inspect: more than headers

hya --inspect URL                 # size, type, modification date
hya --inspect STREAM_MANIFEST_URL # for HLS/DASH: the renditions on offer

Other things you can ask without downloading

hya --preview https://example.com/archive.zip    # list the files inside a ZIP; one small ranged request
hya --list-streams https://example.com/live.m3u8 # list a stream's renditions
hya checksum URL                                 # the digest the server publishes
hya metalink FILE_OR_URL                         # what a Metalink document offers

Fetch and throw away

--no-save runs the real transfer and discards the bytes. Use it to test a mirror's speed or compute a checksum:

hya --no-save --print-checksum URL
hya --no-save --json URL            # size, timings and format as JSON

Cookies and logged-in downloads

Some files sit behind a login: a university mirror, a private GitLab artifact, a forum attachment, a paywalled dataset. Your browser is already signed in, so you can hand its session to Hydra instead of signing in again.

This section is about using your own sessions, for accounts you are allowed to use. Taking someone else's cookies is session hijacking, and it is not what this feature is for. See Keep it safe.

Take the session from your browser

hya --cookies-from-browser firefox https://example.org/private/file.iso
hya --cookies-from-browser "chrome:Profile 2" https://example.org/private/file.iso
hya --cookies-from-browser safari URL

Supported: Firefox, LibreWolf and Zen; Chrome, Chromium, Edge, Brave, Vivaldi and Opera; Safari. Add :PROFILE to pick a profile other than the default. A running browser does not need to be closed: Hydra reads a copy of its cookie store.

Hydra tells you which file it read and for which host, so it is never silent about it. It keeps only the cookies for the host you are downloading from and discards the rest of the profile before the first request.

macOS: Full Disk Access

A browser profile is protected by macOS. On the first run Hydra says it cannot read the store and names the path. Grant Full Disk Access to the app that runs Hydra (your terminal, or Hydra itself for the desktop app) in System Settings > Privacy & Security, then run it again. See macOS Permissions Guide.

Pass a cookie yourself

Copy the cookie from your browser's developer tools (Application or Storage tab):

hya --cookie "session=abc; csrf=def" https://example.org/file.iso

-b is the short form. An argument containing = is a cookie string; anything else is treated as a file name, the way curl does it:

hya -b cookies.txt https://example.org/file.iso

Add other headers the same way when a site wants them:

hya --cookie "session=abc" -H "Referer: https://example.org/downloads" URL

Cookie files

A Netscape cookies.txt, the format browser export extensions and curl use:

hya --cookie-jar jar.txt URL           # read before the first request, written back at the end
hya --load-cookies cookies.txt URL     # read only
hya --save-cookies cookies.txt URL     # write the jar when the transfer finishes

--cookie-jar does both directions, which lets a rotating session survive between runs.

Session cookies are the ones a browser drops on exit, and the ones that usually hold your login. They are not written to the jar unless you ask:

hya --save-cookies jar.txt --keep-session-cookies URL
hya --load-cookies jar.txt --junk-session-cookies URL    # ignore the session cookies in the file

Redirects

A session handed out in a redirect chain, such as a login-gated CDN, works with no flag: a Set-Cookie on a 302 is kept for the rest of that chain, then dropped. Nothing touches the disk unless you asked.

A login-protected list of files

hya --cookies-from-browser firefox --input-file urls.txt

Keep it safe

  • A cookie is a password. Anyone who holds a live session cookie is you, without needing your password or your second factor. Do not paste one into a chat, an issue, a screenshot or a shell history you share.
  • Hydra won't leak it. Cookies are selected by the host of the request about to be sent, so a redirect to another site carries that site's cookies and nothing else. A cookie cannot be widened to a public suffix. Values are never logged, at any -v level.
  • Jar files are 0600: owner-only. Keep them out of git and cloud-synced folders, and delete them when you are done.
  • Prefer --cookies-from-browser to copying cookies around. It writes nothing, it reads only the host you are downloading from, and it says what it read.
  • Credentials are separate. For HTTP Basic login use -u user:password; Hydra sends it to the host you named and drops it on a redirect to another host.
  • Revoke on suspicion. If a cookie leaked, sign out of the site everywhere. That invalidates the session.

Only use sessions for accounts that are yours, or that you have permission to use. Check the site's terms for automated downloads.

Troubleshooting

  • Still redirected to a login page. The session expired, or the site wants another header. Sign in again in the browser and retry. Use -S to see what was sent.

  • "cannot read the store" on macOS. Grant Full Disk Access, as above.

  • Wrong profile. Name it: --cookies-from-browser "chrome:Profile 2".

  • Check what is sent, without downloading:

    hya -S --spider --cookie "session=abc" URL

    > Cookie: session=abc appears in the request lines. Remember that this prints the cookie to your terminal.


Run a remote script without saving it

The curl ... | bash pattern, with hya. Send the download to stdout and nothing touches the disk.

hya --stdout -q https://example.com/install.sh | bash
  • --stdout writes the file to standard output instead of a file.
  • -q silences the progress display, so only the script reaches the pipe.

The shell sees the script exactly as served. A tested example:

$ hya --stdout -q http://127.0.0.1:8791/s.sh | bash
hello-from-remote

Pass arguments to the script

hya --stdout -q https://example.com/install.sh | bash -s -- --yes --prefix ~/.local

Look first, then run

Piping straight to a shell runs whatever the server sends. Check it before you trust it.

hya --stdout -q URL | less                               # read it
hya --stdout -q URL | tee /tmp/install.sh | sha256sum    # fingerprint it

Compare against a published hash before running:

hya --stdout -q URL | sha256sum
# compare with the hash on the project's release page, then:
hya --stdout -q URL | bash

Two separate fetches can differ, and a malicious server could serve a clean script to the first and another to the second. Download once into a file when that matters:

hya --checksum sha256:HEX -O install.sh URL && bash install.sh

--checksum refuses a file that doesn't match, and the script never runs.

Other interpreters

hya --stdout -q https://example.com/setup.py | python3 -
hya --stdout -q https://example.com/setup.ps1 | pwsh -c -

Install Hydra itself this way

curl -fsSL https://raw.githubusercontent.com/ja7ad/hydra/main/install.sh | bash
# or, once hya is installed:
hya --stdout -q https://raw.githubusercontent.com/ja7ad/hydra/main/install.sh | bash -s -- --cli

Notes

  • Use -q or --no-progress. Without them, progress goes to your terminal (stderr), not into the pipe, but -q keeps the output clean.
  • On an HTTP error such as a 404, Hydra writes nothing to the pipe, so an error page never reaches your shell.

Reed-Solomon bitrot protection

A flipped bit on a disk, a bad sector, a corrupted copy: your file no longer matches what you downloaded, and the server may be gone. Reed-Solomon parity lets you repair the file locally, with no network.

You make a parity file once, while the file is still good. If chunks are later damaged, hya parity repair rebuilds them.

1. Download and write a manifest

The manifest records a checksum for every chunk (4 MiB by default). It tells the repair step which chunks are damaged.

hya --emit-manifest data.manifest https://example.com/data.bin

Use --chunk-size BYTES for a different grid.

2. Make parity

hya parity make --manifest data.manifest --parity 2 data.bin
parity: 1 data + 2 parity shards of 4194304 B, window 65536 B -> data.bin.parity
  repairs up to 2 damaged shard(s); resident memory 0.2 MB, independent of file size
Option Default Does
--manifest FILE required The manifest from step 1
--parity N 2 Parity shards. Repair works if the damaged chunks number no more than N
--out FILE data.bin.parity Where to write the parity
--window BYTES built in Repair window; memory use depends on this, not on the file size

More parity means more safety and a bigger parity file. --parity 2 survives any two damaged chunks.

Keep the parity on a different disk. Disk errors tend to hit neighbouring sectors, so parity stored next to its data can be lost with it. Use --out /mnt/backup/data.bin.parity.

Keep the manifest too. Without it there is no repair, because a decoder cannot tell a corrupt chunk from a good one.

3. Repair later

See what would be fixed, without writing:

hya parity repair --manifest data.manifest data.bin --dry-run
data.bin: 1 damaged chunk(s): [0]
  (dry run: 1 shard(s) would be repaired)

Then repair:

hya parity repair --manifest data.manifest data.bin
data.bin: 1 damaged chunk(s): [0]
repaired 1 shard(s); all chunks now verify

If the parity is not beside the file, say where it is:

hya parity repair --manifest data.manifest --parity-file /mnt/backup/data.bin.parity data.bin

If more chunks are damaged than you made parity for, repair fails and tells you so. Nothing is half-fixed.

Other ways to use the manifest

The same manifest repairs a download over the network, one chunk at a time, instead of fetching the file again:

hya --chunk-digests data.manifest URL

Chunks are checked as they arrive, and a bad one is fetched again.


Remote checksum lookup

Hydra can read the digest a publisher has already computed, without downloading the file, and can verify a download against one.

What the server advertises

hya checksum https://example.com/release.tar.gz

Hydra looks in the response headers, then for a sidecar such as release.tar.gz.sha256, then for a SHA256SUMS manifest in the same directory.

This checks the bytes against what the publisher claims. It does not check the publisher: a compromised server can publish a matching hash for a bad file. Compare against a hash you got from somewhere else when it matters.

It prints the size and every digest the server publishes. If nothing is advertised, you get an honest answer:

  no digest advertised by the server
  to compute one, the bytes must be transferred: --download-if-needed
Option Does
--verify FILE Compare a local file against the advertised digest
--json Machine-readable output
--no-sidecars Headers only; skip the extra requests for .sha256 and SHA256SUMS
--download-if-needed Stream the whole object and hash it when nothing is advertised

Is my copy current?

hya checksum --verify ./release.tar.gz https://example.com/release.tar.gz

Without downloading the file again. If the server advertises no digest you can compare against, the answer says so instead of guessing.

Check while downloading

Pass the hash you expect. A mismatch fails the download:

hya --checksum sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 URL

md5:, sha1:, sha256: and sha512: are accepted, or a bare hex digest whose length tells Hydra the algorithm. A malformed value is rejected before anything downloads.

Compute the hash of a remote file

hya --no-save --print-checksum URL

Downloads the bytes to hash them and keeps nothing. --print-checksum is also available on a normal download if you want the SHA-256 of what you saved.

Metalink

A Metalink document carries the expected hash, so the download is verified without --checksum:

hya ./Fedora-Workstation.metalink

In scripts

hya checksum --json URL | jq .

Clone this wiki locally