nextcloud/all-in-one · error · \Exception

Could not log in to deSEC: invalid email address or password

Error message

Could not log in to deSEC: invalid email address or password.

What it means

deSEC answered POST /auth/login/ with 400 or 403, which the manager maps to invalid email address or password. 400 typically means a malformed login request (bad email syntax, missing field); 403 means the credentials were checked and rejected.

Source

Thrown at php/src/Desec/DesecManager.php:254

    /**
     * Authenticates with an existing deSEC account and returns the API token issued for it.
     *
     * @throws \Exception on invalid credentials, network failure, or an unexpected HTTP response
     */
    public function loginAccount(string $email, string $password): string {
        try {
            $res = $this->guzzleClient->post($this->configurationManager->desecApiBase . '/auth/login/', [
                'json' => ['email' => $email, 'password' => $password],
            ]);
        } catch (TransferException $e) {
            throw new \Exception('Could not reach the deSEC API: ' . $e->getMessage());
        }

        $code = $res->getStatusCode();
        $body = $res->getBody()->getContents();

        if ($code === 400 || $code === 403) {
            throw new \Exception('Could not log in to deSEC: invalid email address or password.');
        }

        if ($code !== 200 && $code !== 201) {
            throw new \Exception('Unexpected response from deSEC during login (HTTP ' . $code . '): ' . $body);
        }

        $data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
        if (!is_array($data) || !isset($data['token']) || !is_string($data['token'])) {
            throw new \Exception('Could not extract the API token from the deSEC login response. Please try again.');
        }

        return $data['token'];
    }

    /**
     * Registers a dedyn.io domain for the authenticated account.
     * When $slug is empty a random 10-character slug is tried up to MAX_SLUG_ATTEMPTS times.
     *

View on GitHub (pinned to 6b788eec5e)

Solutions

  1. Re-enter the deSEC password carefully, checking for typos and stray whitespace
  2. Confirm the email address is exactly the one the deSEC account is registered under
  3. If forgotten, reset the password at desec.io first, then retry
  4. Make sure the account's verification email was clicked — unverified accounts cannot log in
Defensive patterns

Strategy: try-catch

Validate before calling

// Normalize inputs before login
$email = trim($email);
$password = rtrim($password, " \t\n\r");
if ($email === '' || $password === '') {
    throw new \InvalidArgumentException('Email and password are both required.');
}

Try / catch

try {
    $token = $manager->loginAccount($email, $password);
} catch (\Exception $e) {
    if ($e->getMessage() === 'Could not log in to deSEC: invalid email address or password.') {
        showFieldError('password', 'Wrong deSEC credentials — re-enter or reset at desec.io');
        return;
    }
    throw $e;
}

Prevention

When it happens

Trigger: Wrong password for the existing account; email with a typo; empty password; the account's password was changed or reset at desec.io after AIO generated one; 403 can also follow repeated failed attempts.

Common situations: User reuses an old password after changing it on desec.io; user believes a new account was created but the email already existed (so the generated password never applied); paste artifacts like trailing whitespace in the password field.

Related errors


AI-assisted analysis of nextcloud/all-in-one@6b788eec5e (2026-08-21). Data as JSON: /api/errors/270b8e6e0bc5925a. Report an issue: GitHub.