apolloconfig/apollo · error · BadRequestException

AccessKey should disable first

Error message

AccessKey should disable first

What it means

A BadRequestException (HTTP 400) thrown from AccessKeyService.delete() when the access key being deleted is still enabled (accessKey.isEnabled() returns true). Apollo requires that an access key be disabled before it can be soft-deleted, preventing accidental removal of an active credential that clients are still using for authentication.

Source

Thrown at apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AccessKeyService.java:92

    accessKey.setMode(entity.getMode());
    accessKey.setEnabled(entity.isEnabled());
    accessKey.setDataChangeLastModifiedBy(operator);
    accessKeyRepository.save(accessKey);

    auditService.audit(AccessKey.class.getSimpleName(), id, Audit.OP.UPDATE, operator);
    return accessKey;
  }

  @Transactional
  public void delete(String appId, long id, String operator) {
    AccessKey accessKey = accessKeyRepository.findOneByAppIdAndId(appId, id);
    if (accessKey == null) {
      throw BadRequestException.accessKeyNotExists();
    }

    if (accessKey.isEnabled()) {
      throw new BadRequestException("AccessKey should disable first");
    }

    accessKey.setDeleted(Boolean.TRUE);
    accessKey.setDataChangeLastModifiedBy(operator);
    accessKeyRepository.save(accessKey);

    auditService.audit(AccessKey.class.getSimpleName(), id, Audit.OP.DELETE, operator);
  }
}

View on GitHub (pinned to d95fc18d11)

Solutions

  1. First call update to set enabled=false on the access key, then call delete.
  2. In automated workflows, always follow the sequence: update(disable) → verify no clients break → delete.
  3. Check the enabled status before attempting deletion and branch accordingly.

Example fix

// before: try to delete an enabled key
accessKeyApi.delete(appId, keyId); // fails if enabled

// after: disable first, then delete
AccessKeyDTO update = new AccessKeyDTO();
update.setId(keyId);
update.setEnabled(false);
update.setDataChangeLastModifiedBy(operator);
accessKeyApi.update(appId, update);
// ... wait for clients to stop using the key ...
accessKeyApi.delete(appId, keyId); // now succeeds
Defensive patterns

Strategy: validation

Validate before calling

// Disable the key before attempting deletion
if (accessKey.isEnabled()) {
    AccessKeyDTO update = new AccessKeyDTO();
    update.setId(accessKey.getId());
    update.setEnabled(false);
    update.setDataChangeLastModifiedBy(operator);
    accessKeyApi.update(appId, update);
}
accessKeyApi.delete(appId, accessKey.getId());

Prevention

When it happens

Trigger: DELETE access key call (AccessKeyService.delete) for a key whose enabled flag is true. The key must first be updated to enabled=false via AccessKeyService.update before delete will succeed.

Common situations: Attempting to delete a key in a single step without disabling it first; a cleanup script that skips the disable step; confusion between the update and delete lifecycle.

Related errors


AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14). Data as JSON: /api/errors/31266a0f44bab128. Report an issue: GitHub.