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
- First call update to set enabled=false on the access key, then call delete.
- In automated workflows, always follow the sequence: update(disable) → verify no clients break → delete.
- 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
- Always follow the disable-then-delete sequence for access keys.
- Check the enabled flag before attempting deletion.
- In automated workflows, add a delay between disable and delete to ensure clients have rotated.
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
- AccessKeys count limit exceeded
- cluster not unique
- value too long. length limit:%s
- key too long. length limit:%s
- type is invalid. type should be in [0, 3].
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/31266a0f44bab128.
Report an issue: GitHub.