Skip to content

[Bug]: Self-service Account/AccountPassword updates 404 — /api/account/stalwart/jmap route not found #627

Description

@sononaco

Description

Attempting to change display name or password from Settings produces a 404. The request never appears to reach the JMAP server — the response Vary header (rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch) indicates the request is being served by Next.js's own not-found handler rather than a registered API route, suggesting /api/account/stalwart/jmap does not exist as a server-side route in this build.

Steps to Reproduce

  1. Deploy Bulwark 1.7.7 via the Docker command above, connected to Stalwart 0.16.11+
  2. Complete the setup wizard, confirming stalwartFeaturesEnabled: true in config.json
  3. Log in as a user
  4. Go to Settings → Display Name (or Change Password)
  5. Submit a change

Expected Behavior

Request succeeds, or fails with a JMAP-level error from Stalwart (e.g. permission denied).

Actual Behavior

POST https://webmail.[redacted]/api/account/stalwart/jmap
Status: 404
Content-Type: application/problem+json
Vary: rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch

Bulwark Version

1.7.7

Stalwart Mail Server Version

0.16.11

Browser

Chrome / Chromium, Safari, Firefox

Operating System

macOS

Screenshots / Screen Recording

See logs.

Relevant Logs or Error Output

Watch the Network tab in developer tools:

Summary
URL: https://webmail.[redacted]/api/account/stalwart/jmap
Status: 404
Source: Network
Address: [removed]:443
Initiator: 
8263-10ced9cc917eb63f.js:1:148736

Request
:method: POST
:scheme: https
:authority: webmail.[redacted]
:path: /api/account/stalwart/jmap
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Content-Length: 175
Content-Type: application/json
Cookie: jmap_stalwart_ctx=[removed]; jmap_session=[removed].
Origin: https://webmail.[redacted]
Pragma: no-cache
Priority: u=3, i
Referer: https://webmail.[redacted]/settings
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.5.2 Safari/605.1.15
X-JMAP-Cookie-Slot: 0

Response
:status: 404
cf-cache-status: DYNAMIC
cf-ray: a1ba93dd8b8b4537-ATL
Content-Type: application/problem+json
Date: Wed, 15 Jul 2026 17:44:52 GMT
nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
Server: cloudflare
Vary: rsc, next-router-state-tree, next-router-prefetch, next-router-segment-prefetch

Request Data
MIME Type: application/json
Request Data:

Additional Context

Deployment:

Bulwark: docker run -d --name bulwark -p 3000:3000 -v bulwark-config:/app/data/admin -v bulwark-state:/app/data/admin-state ghcr.io/bulwarkmail/webmail:latest
Container created 2026-07-09T20:09:35Z (pulled after the 1.7.7 release)
No .env.local or environment variables set; configured entirely through the first-launch setup wizard
Stalwart reachable at https://stalwart.[redacted], fronted by Cloudflare, own domain separate from other Stalwart instances on the network

Troubleshooting already performed (ruling out other causes):

Confirmed config.json has stalwartFeaturesEnabled: true
Confirmed Stalwart's authenticated JMAP session correctly advertises urn:stalwart:jmap for the account, scoped in both accountCapabilities and primaryAccounts
Confirmed direct x:Account/get and x:Account/set calls against Stalwart's own /jmap/ endpoint succeed via curl with admin credentials
Confirmed the user's Stalwart role initially lacked sysAccountUpdate/sysAccountPasswordUpdate; added both permissions via stalwart-cli update role — 404 persisted unchanged, indicating this is not a Stalwart-side permission issue
Confirmed container's running build reports "version": "1.7.7" via package.json, ruling out a stale/outdated image

Given the above, this looks like the self-service Account/AccountPassword route either isn't registered, isn't reachable under this deployment's routing, or has a build/naming mismatch between the client bundle and the server-side route it expects.
Additional context:
Happy to provide further logs, HAR capture, or test on request. This is currently blocking self-service password/display-name management ahead of a Zimbra→Stalwart migration cutover for our organization.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions