[Bug]: SimpleFIN integration reports INVALID_ACCESS_TOKEN even though access token works via SimpleFIN Bridge #2698

Open
opened 2026-02-28 20:24:53 -06:00 by GiteaMirror · 6 comments
Owner

Originally created by @jbrnm on GitHub (Dec 7, 2025).

Verified issue does not already exist?

  • I have searched and found no existing issue

What happened?

Environment

  • Actual Server: 25.12.0 (also reproduced with other releases as far back as 25.9.0)
  • Hosting: Self-hosted, rootless Podman on AlmaLinux behind Traefik
  • Database: Fresh instance (data dir wiped and recreated multiple times)
  • SimpleFIN: SimpleFIN Bridge (https://beta-bridge.simplefin.org)
  • Browser: Firefox (latest)

Summary

The SimpleFIN bank sync integration in Actual consistently reports Invalid SimpleFIN access token. Reset the token and re-link any broken accounts. even when using a freshly generated SimpleFIN setup token, with a corresponding access token that works correctly when used directly against the SimpleFIN Bridge /accounts endpoint.

Suspected Cause

  • Actual’s SimpleFIN integration appears to be:
    • Misinterpreting the SimpleFIN Bridge token (for example, treating the base64 setup token as an access key directly), or
    • Exchanging it in a way that’s incompatible with the current Bridge behavior.
  • Since the token and access URL work via the documented SimpleFIN Bridge flow, the error likely lies in how Actual is using the token rather than in SimpleFIN itself.

Questions

  • Has the SimpleFIN Bridge flow changed in a way that requires updating Actual’s SimpleFIN client (for example, path changes, versioned endpoints, or token format changes)? I do notice that I'm being logged into a Bridge tagged "beta", but this appears to be their default production endpoint. As a new user of SimpleFIN, I'm unsure if this has long been the expected behavior.

Happy to provide more logs or test any patches/config changes if helpful.

How can we reproduce the issue?

Steps to Reproduce

  1. In SimpleFIN Bridge, generate a Setup Token (the base64 string from the “Developer Guide” flow).
  2. In Actual:
    • Start from a fresh server instance
    • Complete initial setup and open a new budget.
    • Go to Bank Sync → SimpleFIN and paste the setup token as instructed.
  3. Attempt to link accounts via SimpleFIN.

Variant attempted: base64 setup token pasted directly; also tried using the derived ACCESS_URL (see Diagnostics).

Expected Behavior

  • Actual successfully exchanges the SimpleFIN setup token for an access token and uses it to:
    • Validate the token.
    • List SimpleFIN accounts.
    • Allow linking accounts without error.

Actual Behavior

  • The UI shows an error toast and console error:

    Error: Invalid SimpleFIN access token.  Reset the token and re-link any broken accounts.
        at m (CreateAccountModal.tsx:91)
        ...
    
  • Repeated attempts with newly generated SimpleFIN tokens (after revoking old ones in SimpleFIN) produce the same behavior.

  • Browser devtools Network panel shows POST /simplefin/accounts responding with:

    {
      "status": "ok",
      "data": {
        "error_type": "INVALID_ACCESS_TOKEN",
        "error_code": "INVALID_ACCESS_TOKEN",
        "status": "rejected",
        "reason": "Invalid SimpleFIN access token.  Reset the token and re-link any broken accounts."
      }
    }
    
  • The UI gets stuck in a “SimpleFIN dance” where it keeps asking for the token again.

Server Logs

From podman logs actual during attempts:

... (normal startup)
Listening on 0.0.0.0:5006...
2025-12-06T18:38:40.052Z info: POST 200 /pluggyai/status
2025-12-06T18:38:40.054Z info: POST 200 /simplefin/status
2025-12-06T18:38:40.056Z info: POST 200 /gocardless/status
2025-12-06T18:38:41.145Z info: POST 200 /simplefin/accounts
...
2025-12-06T18:38:49.815Z info: POST 200 /simplefin/status
2025-12-06T18:38:49.817Z info: POST 200 /gocardless/status
2025-12-06T18:38:50.582Z info: POST 200 /simplefin/accounts
...
2025-12-06T18:41:08.689Z info: POST 200 /gocardless/status
2025-12-06T18:41:08.693Z info: POST 200 /simplefin/status
2025-12-06T18:41:09.966Z info: POST 200 /simplefin/accounts

All relevant SimpleFIN endpoints return HTTP 200; there are no TypeError: fetch failed or ETIMEDOUT stack traces like in issue #5346.

Diagnostics Against SimpleFIN Bridge

Using several setup tokens, I verified the SimpleFIN flow outside of Actual:

  1. Decode setup token → claim URL

    import base64
    setup_token = "<BASE64_SETUP_TOKEN>"
    claim_url = base64.b64decode(setup_token).decode("utf-8")
    # claim_url == "https://beta-bridge.simplefin.org/simplefin/claim/..."
    
  2. Exchange setup token for access URL

    import requests
    resp = requests.post(claim_url, timeout=20, verify=False)
    resp.status_code  # == 200
    access_url = resp.text.strip()  # e.g. "https://<username>:<password>@beta-bridge.simplefin.org/simplefin/v2/..."
    
  3. Use access URL to fetch accounts

    import requests, json, datetime, time
    
    accounts_url = access_url.rstrip("/") + "/accounts"
    end_dt = datetime.datetime.now()
    start_dt = end_dt - datetime.timedelta(days=5)
    params = {
        "start-date": int(time.mktime(start_dt.timetuple())),
        "end-date": int(time.mktime(end_dt.timetuple())),
        "pending": 1,
    }
    r = requests.get(accounts_url, params=params, timeout=20, verify=False)
    print(r.status_code)          # 200
    print(r.json().keys())        # ['errors', 'accounts', 'x-api-message']
    print(r.json()['errors'])     # []
    

This confirms:

  • The setup token is valid (claim succeeds with 200).
  • The resulting access URL is valid (accounts request returns 200, with no errors)

Yet when the same setup token is given to Actual, POST /simplefin/accounts returns INVALID_ACCESS_TOKEN. Throughout testing, I confirmed that the payload of the POST /secret request in the browser Network tab exactly matches the current SimpleFIN setup token value I generated in the Bridge UI.

Where are you hosting Actual?

Docker

What browsers are you seeing the problem on?

Firefox

Operating System

Linux

Originally created by @jbrnm on GitHub (Dec 7, 2025). ### Verified issue does not already exist? - [x] I have searched and found no existing issue ### What happened? ## Environment - Actual Server: `25.12.0` (also reproduced with other releases as far back as `25.9.0`) - Hosting: Self-hosted, rootless Podman on AlmaLinux behind Traefik - Database: Fresh instance (data dir wiped and recreated multiple times) - SimpleFIN: SimpleFIN Bridge (`https://beta-bridge.simplefin.org`) - Browser: Firefox (latest) ## Summary The SimpleFIN bank sync integration in Actual consistently reports `Invalid SimpleFIN access token. Reset the token and re-link any broken accounts.` even when using a freshly generated SimpleFIN setup token, with a corresponding access token that works correctly when used directly against the SimpleFIN Bridge `/accounts` endpoint. ## Suspected Cause - Actual’s SimpleFIN integration appears to be: - Misinterpreting the SimpleFIN Bridge token (for example, treating the base64 setup token as an access key directly), or - Exchanging it in a way that’s incompatible with the current Bridge behavior. - Since the token and access URL work via the [documented SimpleFIN Bridge flow](https://beta-bridge.simplefin.org/info/developers), the error likely lies in how Actual is using the token rather than in SimpleFIN itself. ## Questions - Has the SimpleFIN Bridge flow changed in a way that requires updating Actual’s SimpleFIN client (for example, path changes, versioned endpoints, or token format changes)? I do notice that I'm being logged into a Bridge tagged "beta", but this appears to be their default production endpoint. As a new user of SimpleFIN, I'm unsure if this has long been the expected behavior. Happy to provide more logs or test any patches/config changes if helpful. ### How can we reproduce the issue? ## Steps to Reproduce 1. In SimpleFIN Bridge, generate a **Setup Token** (the base64 string from the “Developer Guide” flow). 2. In Actual: - Start from a fresh server instance - Complete initial setup and open a new budget. - Go to Bank Sync → SimpleFIN and paste the setup token as instructed. 3. Attempt to link accounts via SimpleFIN. _Variant attempted:_ base64 setup token pasted directly; also tried using the derived `ACCESS_URL` (see Diagnostics). ## Expected Behavior - Actual successfully exchanges the SimpleFIN setup token for an access token and uses it to: - Validate the token. - List SimpleFIN accounts. - Allow linking accounts without error. ## Actual Behavior - The UI shows an error toast and console error: ```text Error: Invalid SimpleFIN access token. Reset the token and re-link any broken accounts. at m (CreateAccountModal.tsx:91) ... ``` - Repeated attempts with newly generated SimpleFIN tokens (after revoking old ones in SimpleFIN) produce the same behavior. - Browser devtools Network panel shows `POST /simplefin/accounts` responding with: ```json { "status": "ok", "data": { "error_type": "INVALID_ACCESS_TOKEN", "error_code": "INVALID_ACCESS_TOKEN", "status": "rejected", "reason": "Invalid SimpleFIN access token. Reset the token and re-link any broken accounts." } } ``` - The UI gets stuck in a “SimpleFIN dance” where it keeps asking for the token again. ## Server Logs From `podman logs actual` during attempts: ```text ... (normal startup) Listening on 0.0.0.0:5006... 2025-12-06T18:38:40.052Z info: POST 200 /pluggyai/status 2025-12-06T18:38:40.054Z info: POST 200 /simplefin/status 2025-12-06T18:38:40.056Z info: POST 200 /gocardless/status 2025-12-06T18:38:41.145Z info: POST 200 /simplefin/accounts ... 2025-12-06T18:38:49.815Z info: POST 200 /simplefin/status 2025-12-06T18:38:49.817Z info: POST 200 /gocardless/status 2025-12-06T18:38:50.582Z info: POST 200 /simplefin/accounts ... 2025-12-06T18:41:08.689Z info: POST 200 /gocardless/status 2025-12-06T18:41:08.693Z info: POST 200 /simplefin/status 2025-12-06T18:41:09.966Z info: POST 200 /simplefin/accounts ``` All relevant SimpleFIN endpoints return HTTP 200; there are no `TypeError: fetch failed` or `ETIMEDOUT` stack traces like in issue #5346. ## Diagnostics Against SimpleFIN Bridge Using several setup tokens, I verified the SimpleFIN flow outside of Actual: 1. **Decode setup token → claim URL** ```python import base64 setup_token = "<BASE64_SETUP_TOKEN>" claim_url = base64.b64decode(setup_token).decode("utf-8") # claim_url == "https://beta-bridge.simplefin.org/simplefin/claim/..." ``` 2. **Exchange setup token for access URL** ```python import requests resp = requests.post(claim_url, timeout=20, verify=False) resp.status_code # == 200 access_url = resp.text.strip() # e.g. "https://<username>:<password>@beta-bridge.simplefin.org/simplefin/v2/..." ``` 3. **Use access URL to fetch accounts** ```python import requests, json, datetime, time accounts_url = access_url.rstrip("/") + "/accounts" end_dt = datetime.datetime.now() start_dt = end_dt - datetime.timedelta(days=5) params = { "start-date": int(time.mktime(start_dt.timetuple())), "end-date": int(time.mktime(end_dt.timetuple())), "pending": 1, } r = requests.get(accounts_url, params=params, timeout=20, verify=False) print(r.status_code) # 200 print(r.json().keys()) # ['errors', 'accounts', 'x-api-message'] print(r.json()['errors']) # [] ``` This confirms: - The setup token is valid (claim succeeds with 200). - The resulting access URL is valid (accounts request returns 200, with no errors) Yet when the same setup token is given to Actual, `POST /simplefin/accounts` returns `INVALID_ACCESS_TOKEN`. Throughout testing, I confirmed that the payload of the `POST /secret` request in the browser Network tab exactly matches the current SimpleFIN setup token value I generated in the Bridge UI. ### Where are you hosting Actual? Docker ### What browsers are you seeing the problem on? Firefox ### Operating System Linux
GiteaMirror added the bank syncbug labels 2026-02-28 20:24:53 -06:00
Author
Owner

@Ellessm commented on GitHub (Dec 9, 2025):

I'd like to add that I've encountered this same behavior on my self hosted actual server running on a raspberry pi 4. I asked the discord for assistance and was directed to this thread.

In the end, I was able to fix my server by using a different machine (docker through orbstack on an m4 Mac mini - an expensive solution). I tried to restore my server using my latest backups, but the same error was encountered until I used an older backup dating to 11-07-2025. My connection to simpleFin was fixed and I was able to reimport all the transactions from the past month. Note that restoring this same backup did not work on the raspberry pi 4; the simplefin connection remained broken. On both machines, I used the same docker-compose.yml configuration, and both servers were accessed through a reverse proxy using Caddy.

@Ellessm commented on GitHub (Dec 9, 2025): I'd like to add that I've encountered this same behavior on my self hosted actual server running on a raspberry pi 4. I asked the discord for assistance and was directed to this thread. In the end, I was able to fix my server by using a different machine (docker through orbstack on an m4 Mac mini - an expensive solution). I tried to restore my server using my latest backups, but the same error was encountered until I used an older backup dating to 11-07-2025. My connection to simpleFin was fixed and I was able to reimport all the transactions from the past month. Note that restoring this same backup did not work on the raspberry pi 4; the simplefin connection remained broken. On both machines, I used the same docker-compose.yml configuration, and both servers were accessed through a reverse proxy using Caddy.
Author
Owner

@jbrnm commented on GitHub (Dec 16, 2025):

Just to add another data point, I was ultimately able to get Actual Budget's SimpleFIN syncing working using the macOS desktop application. And this from the same LAN my AlmaLinux container server runs on. The one running on my server still does not work with the same pattern as before. So it would seem this may be an edge case bug having something to do with some aspect of my specific configuration: AlmaLinux 10, Podman, Traefik or Firefox (also tested with Brave and Google Chrome). Happy to provide my configuration files if it would be useful in diagnosing the issue.

@jbrnm commented on GitHub (Dec 16, 2025): Just to add another data point, I was ultimately able to get Actual Budget's SimpleFIN syncing working using the macOS desktop application. And this from the same LAN my AlmaLinux container server runs on. The one running on my server still does not work with the same pattern as before. So it would seem this may be an edge case bug having something to do with some aspect of my specific configuration: AlmaLinux 10, Podman, Traefik or Firefox (also tested with Brave and Google Chrome). Happy to provide my configuration files if it would be useful in diagnosing the issue.
Author
Owner

@mazarian commented on GitHub (Jan 17, 2026):

I'm experiencing the same issue. It was working fine, then stopped working. I'm seeing the following in my logs:

Jan 17 08:28:19 Error: Invalid access key
Jan 17 08:28:19 Invalid SimpleFIN access key
Jan 17 08:28:19 at /app/code/node_modules/router/index.js:295:15
Jan 17 08:28:19 at file:///app/code/build/src/app-gocardless/util/handle-error.js:3:9
Jan 17 08:28:19 at file:///app/code/build/src/app-simplefin/app-simplefin.js:42:32
Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17)
Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17)
Jan 17 08:28:19 at Route.dispatch (/app/code/node_modules/router/lib/route.js:117:3)
Jan 17 08:28:19 at getAccounts (file:///app/code/build/src/app-simplefin/app-simplefin.js:291:18)
Jan 17 08:28:19 at handle (/app/code/node_modules/router/index.js:435:11)
Jan 17 08:28:19 at next (/app/code/node_modules/router/lib/route.js:157:13)
Jan 17 08:28:19 at parseAccessKey (file:///app/code/build/src/app-simplefin/app-simplefin.js:246:15)
@mazarian commented on GitHub (Jan 17, 2026): I'm experiencing the same issue. It was working fine, then stopped working. I'm seeing the following in my logs: ``` Jan 17 08:28:19 Error: Invalid access key Jan 17 08:28:19 Invalid SimpleFIN access key Jan 17 08:28:19 at /app/code/node_modules/router/index.js:295:15 Jan 17 08:28:19 at file:///app/code/build/src/app-gocardless/util/handle-error.js:3:9 Jan 17 08:28:19 at file:///app/code/build/src/app-simplefin/app-simplefin.js:42:32 Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17) Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17) Jan 17 08:28:19 at Route.dispatch (/app/code/node_modules/router/lib/route.js:117:3) Jan 17 08:28:19 at getAccounts (file:///app/code/build/src/app-simplefin/app-simplefin.js:291:18) Jan 17 08:28:19 at handle (/app/code/node_modules/router/index.js:435:11) Jan 17 08:28:19 at next (/app/code/node_modules/router/lib/route.js:157:13) Jan 17 08:28:19 at parseAccessKey (file:///app/code/build/src/app-simplefin/app-simplefin.js:246:15) ```
Author
Owner

@imlogang commented on GitHub (Jan 18, 2026):

Adding that I am getting this same error now on 26.1.0. Was previously working as of 1/2/26 when I last pulled data.

Was getting issues syncing, and the UI said to try a new token, but a new token is getting this in the network tab.:

Error: Invalid SimpleFIN access token.  Reset the token and re-link any broken accounts.
    m CreateAccountModal.tsx:91
    E usePress.mjs:137
    Ei useEffectEvent.mjs:30
    onClick usePress.mjs:241
    React 6

No errors within the Docker container.
Firefox, Docker 29.1.4 running on Ubuntu server.

@imlogang commented on GitHub (Jan 18, 2026): Adding that I am getting this same error now on 26.1.0. Was previously working as of 1/2/26 when I last pulled data. Was getting issues syncing, and the UI said to try a new token, but a new token is getting this in the network tab.: ``` Error: Invalid SimpleFIN access token. Reset the token and re-link any broken accounts. m CreateAccountModal.tsx:91 E usePress.mjs:137 Ei useEffectEvent.mjs:30 onClick usePress.mjs:241 React 6 ``` No errors within the Docker container. Firefox, Docker 29.1.4 running on Ubuntu server.
Author
Owner

@cco commented on GitHub (Feb 10, 2026):

I'm experiencing the same issue. It was working fine, then stopped working. I'm seeing the following in my logs:

Jan 17 08:28:19 Error: Invalid access key
Jan 17 08:28:19 Invalid SimpleFIN access key
Jan 17 08:28:19 at /app/code/node_modules/router/index.js:295:15
Jan 17 08:28:19 at file:///app/code/build/src/app-gocardless/util/handle-error.js:3:9
Jan 17 08:28:19 at file:///app/code/build/src/app-simplefin/app-simplefin.js:42:32
Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17)
Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17)
Jan 17 08:28:19 at Route.dispatch (/app/code/node_modules/router/lib/route.js:117:3)
Jan 17 08:28:19 at getAccounts (file:///app/code/build/src/app-simplefin/app-simplefin.js:291:18)
Jan 17 08:28:19 at handle (/app/code/node_modules/router/index.js:435:11)
Jan 17 08:28:19 at next (/app/code/node_modules/router/lib/route.js:157:13)
Jan 17 08:28:19 at parseAccessKey (file:///app/code/build/src/app-simplefin/app-simplefin.js:246:15)

Seeing the exact same errors here as well. Just setup actual budget and Simplefin has been flakey from the start. Managed to get most of my accounts imported last night, but while adding the rest today I ran into this error. Attempted to reset the key and am now stuck in endless prompt loop for the auth key.

Update: Well, for whatever reason unlinking a random account and relinking it with a new token resolved the issue for me.

@cco commented on GitHub (Feb 10, 2026): > I'm experiencing the same issue. It was working fine, then stopped working. I'm seeing the following in my logs: > > ``` > Jan 17 08:28:19 Error: Invalid access key > Jan 17 08:28:19 Invalid SimpleFIN access key > Jan 17 08:28:19 at /app/code/node_modules/router/index.js:295:15 > Jan 17 08:28:19 at file:///app/code/build/src/app-gocardless/util/handle-error.js:3:9 > Jan 17 08:28:19 at file:///app/code/build/src/app-simplefin/app-simplefin.js:42:32 > Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17) > Jan 17 08:28:19 at Layer.handleRequest (/app/code/node_modules/router/lib/layer.js:152:17) > Jan 17 08:28:19 at Route.dispatch (/app/code/node_modules/router/lib/route.js:117:3) > Jan 17 08:28:19 at getAccounts (file:///app/code/build/src/app-simplefin/app-simplefin.js:291:18) > Jan 17 08:28:19 at handle (/app/code/node_modules/router/index.js:435:11) > Jan 17 08:28:19 at next (/app/code/node_modules/router/lib/route.js:157:13) > Jan 17 08:28:19 at parseAccessKey (file:///app/code/build/src/app-simplefin/app-simplefin.js:246:15) > ``` Seeing the exact same errors here as well. Just setup actual budget and Simplefin has been flakey from the start. Managed to get most of my accounts imported last night, but while adding the rest today I ran into this error. Attempted to reset the key and am now stuck in endless prompt loop for the auth key. Update: Well, for whatever reason unlinking a random account and relinking it with a new token resolved the issue for me.
Author
Owner

@Cory-Christensen commented on GitHub (Feb 14, 2026):

I'm also experiencing this issue after updating my docker image. I'm running on Synology, Brave Browser. I've also tried the macOS app (still chromium-based); it doesn't work there either.

@Cory-Christensen commented on GitHub (Feb 14, 2026): I'm also experiencing this issue after updating my docker image. I'm running on Synology, Brave Browser. I've also tried the macOS app (still chromium-based); it doesn't work there either.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#2698