How NVM Handles Network Failures and Resumes Interrupted Downloads

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 (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).

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:

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:


# 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) 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →