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

  1. Add the target environment to the portal config emergency-publish allow-list (portal config property) and restart the portal.
  2. Do not use emergency publish for that environment if policy forbids it; resolve the underlying release blocker instead.
  3. Confirm the env string matches exactly (case, spelling) what is configured and what Env.valueOf expects.
  4. 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

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


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