jumpserver/jumpserver · error · JMSException
perm_account_invalid
perm_account_invalid
Error message
Account not found
What it means
Raised in _validate_perm when get_permed_account returns no account or an account with empty actions — i.e. the user has no usable grant of this asset account for the protocol. Code is 'perm_account_invalid'.
Source
Thrown at apps/authentication/api/connection_token.py:737
if ticket:
data['from_ticket'] = ticket
if ticket or self.need_face_verify:
data['is_active'] = False
if self.face_monitor_token:
FaceMonitorContext.get_or_create_context(self.face_monitor_token, self.request.user.id)
data['face_monitor_token'] = self.face_monitor_token
return data
@staticmethod
def get_permed_account(user, asset, account_alias, protocol):
return ConnectionToken.get_user_permed_account(user, asset, account_alias, protocol)
def _validate_perm(self, user, asset, account_alias, protocol):
account = self.get_permed_account(user, asset, account_alias, protocol)
if not account or not account.actions:
msg = _('Account not found')
raise JMSException(code='perm_account_invalid', detail=msg)
if account.date_expired < timezone.now():
msg = _('Permission expired')
raise JMSException(code='perm_expired', detail=msg)
return account
def _record_operate_log(self, acl, asset):
from audits.handler import create_or_update_operate_log
with tmp_to_org(asset.org_id):
after = {
str(_('Assets')): str(asset),
str(_('Account')): self.input_username
}
object_name = acl._meta.object_name
resource_type = acl._meta.verbose_name
create_or_update_operate_log(
acl.action, resource_type, resource=acl,
after=after, object_name=object_name
)View on GitHub (pinned to 6ec464fabd)
Solutions
- Verify the user actually has an asset permission granting this account (check the asset permission's accounts and actions in the admin UI)
- Confirm org context: request with the correct X-JMS-ORG header matching the asset's org
- Re-check exact account username/alias; re-fetch the permed-account list before requesting the token
Defensive patterns
Strategy: try-catch
Validate before calling
accounts = get_user_permed_accounts(user, asset, protocol)
if not any(a['username'] == account_alias and a.get('actions') for a in accounts):
raise PermissionError('no usable grant for this account') Try / catch
try:
resp = client.create_connection_token(...)
except JMSException as e:
if e.code == 'perm_account_invalid':
refresh_permission_cache(); show_grant_dialog() Prevention
- Refresh the permed-account list after permission changes
- Always issue requests within the asset's org context
When it happens
Trigger: Calling connection-token validate/create/exchange for an (asset, account_alias, protocol) combination the user has no asset permission for, or whose grant has empty 'actions'; also when the account alias matches nothing on the asset.
Common situations: Permission was revoked or the grant was created without actions; wrong account name; user from a different organization (get_user_permed_account is org-scoped); stale cached permission list on the client side.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Anonymous account is not supported for this asset
- perm_expired
- acl_reject
- user `{}` not has asset `{}` permission for login `{}`
- Approval belongs to another user.
AI-assisted analysis of jumpserver/jumpserver@6ec464fabd (2026-08-28).
Data as JSON: /api/errors/f8b2d8bd0581177c.
Report an issue: GitHub.