roundcube/roundcubemail · error · Exception

Failed to fetch data, HTTP status

Error message

Failed to fetch data, HTTP status {$code}

What it means

The Stalwart password driver's fetch_user() issues an HTTP GET to the Stalwart admin API and only accepts HTTP 200. Any other status code (401/403 auth failure, 404 wrong endpoint, 5xx server error) causes this generic exception, which propagates out of save() when a user tries to change their password.

Solutions

  1. Verify plugins/password config for the stalwart driver: correct host, port, API path, and admin credentials (test with curl against the same URL).
  2. Check the HTTP status code in the Roundcube error log / PHP log to identify 401 (auth) vs 404 (path) vs 5xx (server).
  3. Confirm TLS certificates are valid; if using self-signed certs configure the HTTP client options accordingly.
  4. Check Stalwart server logs for the corresponding request and error detail.

Example fix

// before
throw new \Exception("Failed to fetch data, HTTP status {$code}");
// after
throw new \Exception("Failed to fetch user from Stalwart, HTTP status {$code}, url: {$url}");
Defensive patterns

Strategy: try-catch

Validate before calling

// before changing password, probe the Stalwart API
$ch = curl_init($apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$httpCode = curl_getinfo(curl_exec($ch) ? $ch : $ch, CURLINFO_RESPONSE_CODE);
if ($httpCode !== 200) { /* abort and show admin error */ }

Try / catch

try { $driver->save($curpass, $newpass, $username); } catch (\Exception $e) { rcube::raise_error(['message' => 'Password change failed: ' . $e->getMessage()], true, false); return false; }

Prevention

When it happens

Trigger: save() -> fetch_user() with a Stalwart host returning non-200: wrong API URL/path, expired or wrong admin credentials in the driver config, Stalwart unreachable via TLS mismatch, or Stalwart returning 5xx during the lookup of the user record.

Common situations: Roundcube password plugin configured with wrong stalwart_host/api path or stale admin token; Stalwart upgraded and endpoint moved; reverse proxy returning 404/502; DNS/firewall issues in production.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of roundcube/roundcubemail@4b54c2acfb (2026-09-14). Data as JSON: /api/errors/c8912bf3ffdd3e01. Report an issue: GitHub.

Appendix: source

Thrown at plugins/password/drivers/stalwart.php:59

    private function fetch_user($username)
    {
        $config = rcmail::get_instance()->config;
        $url = $config->get('password_stalwart_api_host');
        $token = $config->get('password_stalwart_api_token');

        $client = password::get_http_client();
        $response = $client->request('GET', $url . '/principal/' . $username, [
            'headers' => [
                'Authorization' => 'Bearer ' . $token,
                'Accept' => 'application/json',
            ],
        ]);

        $code = $response->getStatusCode();
        $resp = (string) $response->getBody();

        if ($code !== 200) {
            throw new \Exception("Failed to fetch data, HTTP status {$code}");
        }

        return json_decode($resp, true);
    }

    public function save($curpass, $newpass, $username)
    {
        $client = password::get_http_client();
        $config = rcmail::get_instance()->config;
        $url = $config->get('password_stalwart_api_host');
        $token = $config->get('password_stalwart_api_token');

        try {
            $data = $this->fetch_user($username);

            if (!isset($data['data']['secrets'])) {
                return PASSWORD_ERROR;
            }

View on GitHub (pinned to 4b54c2acfb)