apolloconfig/apollo · error · BadRequestException
Env: %s is not supported emergency publish now
Error message
Env: %s is not supported emergency publish now
What it means
HTTP 400 (BadRequestException). Thrown by NamespaceBranchController.checkEmergencyPublishAllowedForUser when emergencyPublish=true, the caller is a USER or USER_TOKEN (not a CONSUMER/OpenAPI token), and PortalConfig.isEmergencyPublishAllowed(env) returns false for that environment. Emergency publish is a per-env opt-in feature; it lets an admin force-publish even when normal release gates would block. Only environments explicitly enabled in portal config permit it.
Source
Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/NamespaceBranchController.java:261
}
private boolean canDeleteBranch(String appId, String env, String clusterName,
String namespaceName, String branchName) {
boolean hasReleasePermission = unifiedPermissionValidator.hasReleaseNamespacePermission(appId,
env, clusterName, namespaceName);
boolean hasModifyPermission = unifiedPermissionValidator.hasModifyNamespacePermission(appId,
env, clusterName, namespaceName);
return hasReleasePermission || (hasModifyPermission && releaseService.loadLatestRelease(appId,
Env.valueOf(env), branchName, namespaceName) == null);
}
private void checkEmergencyPublishAllowedForUser(String env, boolean emergencyPublish) {
String authType = UserIdentityContextHolder.getAuthType();
if (emergencyPublish
&& (UserIdentityConstants.USER.equals(authType)
|| UserIdentityConstants.USER_TOKEN.equals(authType))
&& !portalConfig.isEmergencyPublishAllowed(Env.valueOf(env))) {
throw new BadRequestException("Env: %s is not supported emergency publish now", env);
}
}
private String resolveOperator(String queryOperator, String payloadOperator) {
String authType = UserIdentityContextHolder.getAuthType();
if (UserIdentityConstants.USER.equals(authType)
|| UserIdentityConstants.USER_TOKEN.equals(authType)) {
UserInfo loginUser = userInfoHolder.getUser();
if (loginUser == null || StringUtils.isBlank(loginUser.getUserId())) {
throw new BadRequestException("Current user not found");
}
return loginUser.getUserId();
}
if (UserIdentityConstants.CONSUMER.equals(authType)) {
String operator = StringUtils.isBlank(queryOperator) ? payloadOperator : queryOperator;
RequestPrecondition.checkArguments(!StringUtils.isContainEmpty(operator),
"operator should not be null or empty");View on GitHub (pinned to d95fc18d11)
Solutions
- Add the target environment to the portal config emergency-publish allow-list (portal config property) and restart the portal.
- Do not use emergency publish for that environment if policy forbids it; resolve the underlying release blocker instead.
- Confirm the env string matches exactly (case, spelling) what is configured and what Env.valueOf expects.
- If you are a CONSUMER/OpenAPI token and still see this, verify the auth type reaching the controller is actually CONSUMER.
Example fix
// before portalConfig.emergencyPublishAllowed = [DEV, FAT] // PROD not listed client.publish(env=PROD, emergencyPublish=true); // 400 // after: enable PROD in portal config portalConfig.emergencyPublishAllowed = [DEV, FAT, PRO] // or drop the flag client.publish(env=PROD, emergencyPublish=false);
Defensive patterns
Strategy: validation
Validate before calling
// Confirm emergency publish is allowed for the env before using the flag.
boolean allowed = portalConfigEmergencyEnvs.contains(env); // from config endpoint/docs
if (!allowed && emergencyPublish) {
// either drop the flag or request the env be added to the allow-list; do NOT call with flag=true
} Type guard
null
Try / catch
try {
client.publish(appId, env, cluster, ns, releaseDTO, /*emergencyPublish*/ true);
} catch (HttpClientErrorException.BadRequest e) {
if (e.getMessage().contains("not supported emergency publish")) {
// fall back to a normal publish, or have ops add the env to emergency allow-list
}
} Prevention
- Only set emergencyPublish=true for environments in the portal emergency-publish allow-list.
- Keep the allow-list config under change control; PROD usually excluded by policy.
- Prefer fixing the release blocker over emergency-publish in steady state.
When it happens
Trigger: POST create/update release on a namespace branch with emergencyPublish=true in the body/query for an environment not listed in the portal's emergency-publish allow-list (e.g. PROD when only DEV/FAT are enabled). Applies to portal SSO users and user-tokens; OpenAPI consumer tokens bypass this specific gate.
Common situations: Ops engineer flips emergencyPublish=true during an incident for PROD, but the portal config apollo.portal.emergency-publish.allowed-envs does not include PROD; a freshly deployed portal without the emergency-publish config; env name casing mismatch in the allow-list.
Related errors
- create namespace failed for: %s
- userIds should not be null or empty
- Consumer already exist
- Token is Illegal
- Namespace's role does not exist. Please check whether namesp
AI-assisted analysis of apolloconfig/apollo@d95fc18d11 (2026-08-14).
Data as JSON: /api/errors/3a541719b1c30f07.
Report an issue: GitHub.