passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException
The authentication failed. The credentials are missing.
Error message
The authentication failed. The credentials are missing.
What it means
Thrown by JwtLoginController::loginPost when the authentication result status is FAILURE_CREDENTIALS_MISSING, meaning the authenticator found no credentials to verify at all (HTTP 400). The full message is 'The authentication failed. The credentials are missing.'
Solutions
- Include a valid GPGAuth challenge token in the request (headers/body as the client protocol requires)
- Complete the GPGAuth handshake stages in order (verify server, then login)
- Inspect the request body actually received server-side for missing fields
- Compare against a working passbolt CLI request to spot the missing credential field
Defensive patterns
Strategy: validation
Validate before calling
if (!challengeToken || !Object.keys(gpgAuthHeaders).length) throw new Error('refusing to call login: no GPGAuth credentials assembled'); Try / catch
try { await login(token); } catch (e) { if (String(e.message).includes('credentials are missing')) { restartGpgAuthHandshake(); } } Prevention
- Complete the GPGAuth handshake stages in order before posting the login
- Log outgoing headers/body in a debug mode to confirm the token is present
- Reuse the protocol implementation from the official client
When it happens
Trigger: POST /auth/jwt/login where the request body/headers contain no recognizable GPG challenge token, so the GpgJwtAuthenticator has nothing to authenticate.
Common situations: Client sent an empty or malformed JSON body; missing X-GPGAuth-* headers on stage 1 of the login; sending the token in the wrong field; skipping the server-verification step and posting directly.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- An authentication token should be provided.
- Conflicting authentication parameters, provide…
- Could not import the user OpenPGP key.
- The authentication failed. The credentials are invalid.
- The authentication token is not valid or has expired.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/7d3ce321a8af6e63.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/JwtAuthentication/src/Controller/JwtLoginController.php:74
}
$result = $this->Authentication->getResult();
if ($result->isValid()) {
$challenge = $result->getData()['challenge'];
$user = $result->getData()['user'];
$uac = new UserAccessControl($user['role']['name'], $user['id']);
UserAction::getInstance()->setUserAccessControl($uac);
$event = new Event(UpdateUserLastLoggedInListener::EVENT_USER_LOGIN_SUCCESS, $this, ['user' => $user]);
$this->getEventManager()->dispatch($event);
$this->success(__('The authentication was a success.'), compact('challenge'));
} else {
$message = __('The authentication failed.') . ' ';
switch ($result->getStatus()) {
case Result::FAILURE_CREDENTIALS_MISSING:
$message .= __('The credentials are missing.');
throw new BadRequestException($message);
case Result::FAILURE_IDENTITY_NOT_FOUND:
$message = __('The user does not exist or is not active or has been deleted.');
throw new NotFoundException($message);
case Result::FAILURE_CREDENTIALS_INVALID:
$message = __('The credentials are invalid.');
throw new BadRequestException($message);
default:
case Result::FAILURE_OTHER:
$message = __('An internal error occurred.');
throw new InternalErrorException($message);
}
}
}
}
View on GitHub (pinned to 31c1bbc10f)