Skip to content

[Bug]: @actual-app/api: postBinary sync fails with network-failure #8168

Description

@latetedemelon

What happened?

On an Alpine/musl Node image, @actual-app/api's downloadBudget() fails at the binary sync step (postBinary to POST /sync/sync) with PostError: network-failure. The identical setup on a Debian Slim Node image works. Same Node 22, same package, same self-hosted server.

try {
  const res = await fetch(url, {                      // Node global fetch (undici)
    method: "POST",
    body: Buffer.from(data),
    headers: {
      "Content-Length": data.length,                  // hand-set, and a NUMBER
      "Content-Type": "application/actual-sync",
      ...headers,
    },
  });
} catch {                                             // bare catch — original error discarded
  throw new PostError("network-failure");
}

Suggested fixes

  • Don't set Content-Length manually in postBinary and let fetch derive it from the body.
  • Catch the cause so it's diagnosable:

How can we reproduce the issue?

  • @actual-app/api 26.6.0, actual-server 26.6.0, alpline container (Node 22)
  • Run a normal api.init({ serverURL, password, dataDir }) + api.downloadBudget(syncId) script.
  • In a alpine container: login + all /sync/* GET succeeds, then download-budget throws:
PostError: network-failure
  at postBinary (@actual-app/api/dist/index.js)
  at _fullSync → initialFullSync → syncBudget → download-budget
  • The same script in a Debian Node 22 container → POST 200 /sync/sync, sync completes.

Where are you hosting Actual?

Docker

What browsers are you seeing the problem on?

Other

Operating System

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    APIIssues with the @actual-app/api packagebugSomething isn't working

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions