# How NVM Handles Network Failures and Resumes Interrupted Downloads

> Learn how NVM handles network failures and resumes interrupted downloads. Discover its robust mechanisms for ensuring download integrity and continuity for seamless installations.

- Repository: [nvm.sh/nvm](https://github.com/nvm-sh/nvm)
- Tags: internals
- Published: 2026-02-27

---

**NVM wraps curl (with wget fallback) in the `nvm_download` function, passing the `-C -` resume flag to automatically continue partial downloads, while `nvm_compare_checksum` and 404 detection ensure corrupted or missing files never contaminate the installation.**

The **nvm-sh/nvm** (Node Version Manager) repository provides a POSIX-compliant shell script for managing multiple Node.js versions. Understanding how nvm handles network failures and resume interrupted downloads is critical for DevOps engineers and developers working in unstable network environments or CI/CD pipelines where large Node.js binaries may fail mid-transfer.

## The Download Architecture: curl, wget, and the nvm_download Wrapper

At the heart of nvm's network resilience is the **`nvm_download`** function defined in [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh) (lines 18-37). This function acts as a thin abstraction layer that detects which download utility is available on the host system.

If **`curl`** is present, nvm uses it as the primary client. If curl is absent, the function gracefully falls back to **`wget`**, translating the same safety flags between the two tools. This ensures consistent behavior across macOS, Linux, and BSD systems regardless of which utility is installed.

## Resume Interrupted Downloads with the -C - Flag

The key mechanism enabling nvm to resume interrupted downloads is the **`-C -`** flag passed to curl (or the equivalent `-c` for wget) within the `nvm_download_artifact` function (lines 30-31 in [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh)).

When you run `nvm install <version>` and the download is interrupted by a network timeout or connection drop, the partial file remains on disk in `$NVM_DIR/.cache` or `/tmp`. On the next execution of `nvm install`, the `-C -` flag instructs curl to automatically continue the transfer from the last byte saved, rather than restarting from zero. This resume capability is particularly valuable when downloading large Node.js tarballs over unreliable connections.

## Error Detection and Integrity Verification

NVM implements multiple layers of validation to prevent corrupted artifacts from being extracted or installed.

### HTTP Error Handling and 404 Detection

The `nvm_download` function passes the **`--fail`** flag to curl (or equivalent error handling for wget), ensuring that HTTP 4xx and 5xx responses return a non-zero exit status immediately. Additionally, after the download completes, nvm explicitly scans the downloaded file for the string "404 Not Found" using `nvm_grep` (lines 36-40). If a mirror returns a 404 page as HTML instead of a proper HTTP error, this secondary check catches the mistake and aborts the installation.

### Checksum Validation with nvm_compare_checksum

After a successful download, `nvm_download_artifact` invokes **`nvm_compare_checksum`** (lines 42-46) to validate the file against the official SHA-256 checksum published by the Node.js project. If the hash does not match—indicating network corruption or a man-in-the-middle attack—nvm immediately removes the corrupt file and returns error code **6** (checksum error), forcing a clean retry on the next attempt.

## Automatic Cleanup and Failure Recovery

NVM ensures that failed downloads never leave the system in an inconsistent state. Within `nvm_download_artifact`, the download command is wrapped in an error handler:

```bash
nvm_download ... || ( rm -rf "${TARBALL}" "${tmpdir}"; ... )

```

This block (referenced around lines 30-34) guarantees that if curl exits with a non-zero status—whether from a network timeout, DNS failure, or HTTP error—the partially written tarball and temporary directory are immediately deleted. The function then returns error code **4** (download failed), signaling to the user that the network operation did not complete.

Because nvm does not implement an internal retry loop, the responsibility for retrying falls to the user or the calling script. However, because the resume flag (`-C -`) preserves partial progress between attempts, simply re-running `nvm install <version>` effectively continues where the previous attempt left off without re-downloading already-received data.

## Practical Example: Simulating a Network Failure

The following shell session demonstrates how nvm behaves when a download is interrupted and subsequently resumed:

```bash

# First attempt – simulate network drop after partial download

nvm install 18.20.0

# Output:

#   Downloading https://nodejs.org/dist/v18.20.0/node-v18.20.0-linux-x64.tar.xz...

#   curl: (18) transfer closed with outstanding read data remaining

#   nvm: download from https://nodejs.org/... failed

# The partial file remains in the cache directory.

# Re-running the command resumes from the last byte:

nvm install 18.20.0

# Output:

#   Resuming download from byte 5242880...

#   Checksums match! Using existing downloaded archive …

#   Now using node v18.20.0

```

In this scenario, the first invocation fails with exit code 4, leaving the partial tarball intact. The second invocation passes the `-C -` flag to curl, which detects the existing file and sends a `Range` header to resume the transfer. After completion, `nvm_compare_checksum` validates the SHA-256 hash before extraction proceeds.

## Summary

- **Resume capability**: The `-C -` flag passed to curl (or `-c` for wget) in `nvm_download_artifact` allows interrupted downloads to continue from the last received byte on the next `nvm install` attempt.
- **Integrity checks**: `nvm_compare_checksum` validates SHA-256 hashes after download, while `nvm_grep` scans for "404 Not Found" text to catch misconfigured mirrors.
- **Error handling**: The `nvm_download` wrapper uses `--fail` to catch HTTP errors immediately, and the `|| ( rm -rf ... )` pattern in `nvm_download_artifact` ensures partial files are deleted on failure.
- **No internal retry**: NVM returns error codes 4 (download failed) or 6 (checksum error) and relies on the user to re-run the command, leveraging the resume flag to avoid redundant data transfer.

## Frequently Asked Questions

### Does nvm automatically retry failed downloads?

No, nvm does not implement an automatic retry loop. When a network failure occurs, the `nvm_download_artifact` function returns error code 4 (download failed) after cleaning up the partial file. To retry, you must manually re-run the `nvm install` command. However, because nvm passes the `-C -` resume flag to curl, the subsequent attempt continues from where the previous transfer stopped rather than starting over.

### How does nvm verify that a downloaded Node.js binary is not corrupted?

After the download completes, nvm invokes `nvm_compare_checksum` (defined in [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh)) to compute the SHA-256 hash of the tarball and compare it against the official checksum published by the Node.js project. If the hashes do not match, nvm removes the corrupted file and exits with error code 6 (checksum error). This ensures that network corruption or man-in-the-middle attacks cannot result in a compromised installation.

### What happens if the Node.js mirror returns a 404 error?

NVM handles 404 errors through two mechanisms. First, the `--fail` flag passed to curl (or equivalent for wget) causes the HTTP client to exit with a non-zero status for any 4xx response. Second, as a safety net against mirrors that return a 404 HTML page with a 200 status code, `nvm_download_artifact` uses `nvm_grep` to scan the downloaded content for the string "404 Not Found". If found, the file is deleted and the installation aborts.

### Can nvm resume downloads if I close my terminal and reopen it later?

Yes. Because nvm stores the partial download in a temporary location (typically `$NVM_DIR/.cache` or `/tmp`) and uses the `-C -` (continue) flag with curl, the partial file persists on disk after a terminal closure or system sleep. When you reopen your terminal and re-run `nvm install <version>`, curl detects the existing partial file and resumes the transfer from the last received byte via an HTTP Range request.