[Bug]: New bank linking: popup stays blank or shows 404; server returns 401 token-not-found for /gocardless/create-web-token despite valid GoCardless creds. Existing accounts still sync. #2560

Closed
opened 2026-02-28 20:19:03 -06:00 by GiteaMirror · 1 comment
Owner

Originally created by @thorrrr on GitHub (Oct 23, 2025).

Environment

Actual Server: v25.10.0 (container actualbudget/actual-server)

Actual Client: v25.10.0

Host: Unraid 7.1.4

Reverse proxy: Caddy sidecar in front of Actual; headers injected only for HTML:

Cross-Origin-Opener-Policy: same-origin-allow-popups

Cross-Origin-Embedder-Policy removed

Cache-Control: no-store

Access path: Tailscale Serve (tailnet-only), HTTPS on :8456 to Caddy :8453, then to Actual on :5006

Also tested via Tailscale HTTP on :8457 bypassing TLS

DNS: MagicDNS; AdGuard on LAN

Clients: Linux (CachyOS), iOS/iPadOS; multiple browsers

What works

Existing linked accounts continue to sync (/sync/sync 200)

Caddy header injection verified locally (COOP same-origin-allow-popups, no COEP)

Container can reach GoCardless directly (Node https.get returns STATUS 302)

What fails

Clicking Link bank in browser opens about:blank and never navigates

Server log often shows only POST /gocardless/get-accounts 200, then nothing

Console and manual fetch from the same origin returns:

POST /gocardless/create-web-token -> 401
body: {"status":"error","reason":"unauthorized","details":"token-not-found"}

Sometimes, when the first call does succeed, later API calls hit:

https://bankaccountdata.gocardless.com/api/v2/requisitions/undefined/ -> 404

Repro steps

Open Actual at https:/redacted.ts.net:8456 (tailnet-only), server online.

Settings → Bank Sync → Save GoCardless Secret ID + Secret Key.

Go to an account, click Link bank in browser.

Popup remains white; no navigation; server logs don’t show requisition creation.

DevTools Console:

fetch('/gocardless/create-web-token', { method:'POST', credentials:'include' })
.then(r => r.json().then(body => ({status:r.status, body})))

→ returns {status: 401, body: {reason:'unauthorized', details:'token-not-found'}}

Expected

Server should return 200 with a web token and the popup should navigate to GoCardless.

Actual

Server responds 401 token-not-found on /gocardless/create-web-token even after saving GC credentials.

On some attempts, server later calls requisitions/undefined (404), i.e. no requisition id was produced.

Diagnostics

Local header check on proxy:

HTTP/1.1 200 OK
Cache-Control: no-store
Cross-Origin-Opener-Policy: same-origin-allow-popups

Tailnet endpoints exist (unauthenticated curl shows expected 401):

curl -i -X POST https://…:8456/gocardless/create-web-token -> 401 token-not-found
curl -i -X POST http://…:8457/gocardless/create-web-token -> 401 token-not-found

Inside container:

getent ahosts bankaccountdata.gocardless.com -> A records only
node https.get('https://bankaccountdata.gocardless.com') -> STATUS 302

Workarounds tried

Removed COEP and set COOP via Cloudflare transforms earlier; switched away from Cloudflare to Tailscale + Caddy sidecar.

Cleared service workers and site data for the 8456 origin; tested multiple browsers and devices.

Rotated GoCardless creds in GC dashboard and re-saved in Actual UI multiple times.

Added explicit upstream headers in Caddy so X-Forwarded-Proto=https, X-Forwarded-Port=8456, Host/X-Forwarded-Host are correct.

Hypothesis

The server is not persisting or loading the newly saved GoCardless credentials on this instance, so /gocardless/create-web-token returns 401 token-not-found. Existing accounts continue syncing using pre-existing access tokens, which masks the underlying config problem. On occasions when web-token succeeds, an additional bug yields requisitions/undefined (404), likely from a bad absolute URL or missing id.

Ask

How can we conclusively reset and re-seed GoCardless credentials on the server (via API or documented CLI), and can we add better logging around /gocardless/create-web-token to distinguish “no credentials configured” from other failures?

Is there a known condition in 25.10 where saving Bank Sync creds does not take effect until a restart (or at all) when behind a reverse proxy?

Attachments available

Server logs filtered around link attempts

Caddyfile block used for Actual

Console screenshot showing 401 token-not-found and “Request failed with status code 404”

Originally created by @thorrrr on GitHub (Oct 23, 2025). Environment Actual Server: v25.10.0 (container actualbudget/actual-server) Actual Client: v25.10.0 Host: Unraid 7.1.4 Reverse proxy: Caddy sidecar in front of Actual; headers injected only for HTML: Cross-Origin-Opener-Policy: same-origin-allow-popups Cross-Origin-Embedder-Policy removed Cache-Control: no-store Access path: Tailscale Serve (tailnet-only), HTTPS on :8456 to Caddy :8453, then to Actual on :5006 Also tested via Tailscale HTTP on :8457 bypassing TLS DNS: MagicDNS; AdGuard on LAN Clients: Linux (CachyOS), iOS/iPadOS; multiple browsers What works Existing linked accounts continue to sync (/sync/sync 200) Caddy header injection verified locally (COOP same-origin-allow-popups, no COEP) Container can reach GoCardless directly (Node https.get returns STATUS 302) What fails Clicking Link bank in browser opens about:blank and never navigates Server log often shows only POST /gocardless/get-accounts 200, then nothing Console and manual fetch from the same origin returns: POST /gocardless/create-web-token -> 401 body: {"status":"error","reason":"unauthorized","details":"token-not-found"} Sometimes, when the first call does succeed, later API calls hit: https://bankaccountdata.gocardless.com/api/v2/requisitions/undefined/ -> 404 Repro steps Open Actual at https:/redacted.ts.net:8456 (tailnet-only), server online. Settings → Bank Sync → Save GoCardless Secret ID + Secret Key. Go to an account, click Link bank in browser. Popup remains white; no navigation; server logs don’t show requisition creation. DevTools Console: fetch('/gocardless/create-web-token', { method:'POST', credentials:'include' }) .then(r => r.json().then(body => ({status:r.status, body}))) → returns {status: 401, body: {reason:'unauthorized', details:'token-not-found'}} Expected Server should return 200 with a web token and the popup should navigate to GoCardless. Actual Server responds 401 token-not-found on /gocardless/create-web-token even after saving GC credentials. On some attempts, server later calls requisitions/undefined (404), i.e. no requisition id was produced. Diagnostics Local header check on proxy: HTTP/1.1 200 OK Cache-Control: no-store Cross-Origin-Opener-Policy: same-origin-allow-popups Tailnet endpoints exist (unauthenticated curl shows expected 401): curl -i -X POST https://…:8456/gocardless/create-web-token -> 401 token-not-found curl -i -X POST http://…:8457/gocardless/create-web-token -> 401 token-not-found Inside container: getent ahosts bankaccountdata.gocardless.com -> A records only node https.get('https://bankaccountdata.gocardless.com') -> STATUS 302 Workarounds tried Removed COEP and set COOP via Cloudflare transforms earlier; switched away from Cloudflare to Tailscale + Caddy sidecar. Cleared service workers and site data for the 8456 origin; tested multiple browsers and devices. Rotated GoCardless creds in GC dashboard and re-saved in Actual UI multiple times. Added explicit upstream headers in Caddy so X-Forwarded-Proto=https, X-Forwarded-Port=8456, Host/X-Forwarded-Host are correct. Hypothesis The server is not persisting or loading the newly saved GoCardless credentials on this instance, so /gocardless/create-web-token returns 401 token-not-found. Existing accounts continue syncing using pre-existing access tokens, which masks the underlying config problem. On occasions when web-token succeeds, an additional bug yields requisitions/undefined (404), likely from a bad absolute URL or missing id. Ask How can we conclusively reset and re-seed GoCardless credentials on the server (via API or documented CLI), and can we add better logging around /gocardless/create-web-token to distinguish “no credentials configured” from other failures? Is there a known condition in 25.10 where saving Bank Sync creds does not take effect until a restart (or at all) when behind a reverse proxy? Attachments available Server logs filtered around link attempts Caddyfile block used for Actual Console screenshot showing 401 token-not-found and “Request failed with status code 404”
GiteaMirror added the bank syncbug labels 2026-02-28 20:19:03 -06:00
Author
Owner

@thorrrr commented on GitHub (Nov 2, 2025):

Internal issue with GoCardless

@thorrrr commented on GitHub (Nov 2, 2025): Internal issue with GoCardless
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#2560