Skip to content

Missing default timeout in NodeHttpStack causes uploads to hang indefinitely #773

Open
@m7kvqbe1

Description

@m7kvqbe1

Issue

When using tus-js-client in Node.js environments, I've discovered that uploads can hang indefinitely with no retry mechanism being triggered, particularly in poor or unreliable network conditions (like satellite connections).

After investigating, I found that NodeHttpStack does not specify any default timeout for HTTP requests. Since Node.js defaults to no timeout (0 = infinite), this means requests can remain in a "stalled" state forever without ever triggering an error that would initiate the retry mechanism.

Impact

This is a critical issue for resumable uploads, especially in environments with unreliable connections:

  • Uploads silently hang with no errors or retries
  • Even when network conditions improve, stalled uploads remain stalled due to TCP backoff
  • Resources remain tied up indefinitely
  • The retry mechanism (a key feature of the library) is never triggered for these cases

Reproduction

  1. Create a Node.js service using tus-js-client
  2. Initiate an upload over an unreliable connection
  3. During upload, introduce severe packet loss or connection degradation
  4. Observe that the upload stalls indefinitely with no retry

Workaround

I've had to copy paste the NodeHttpStack module into our own codebase and modify it to include timeouts. I would have preferred to import the module directly, but it's not properly exported from your library in a way that makes it easily accessible.

The fix was simple:

const httpStack = new NodeHttpStack({
  timeout: 30000, // 30 seconds
})

Proposed Solution

A simple fix would be to:

  1. Add a reasonable default timeout to the NodeHttpStack constructor
  2. Properly export the NodeHttpStack class so it can be imported directly (you let us inject a custom implementation)

This would ensure that hanging connections eventually trigger the retry mechanism, which is essential for a resumable upload library designed for unreliable networks.

Questions

  1. Was this omission intentional, or was it an oversight?
  2. Are there any technical reasons why a default timeout wasn't included?
  3. Would you consider adding a reasonable default timeout in a future release?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions