{"record":{"id":"3a541719b1c30f07","repo":"apolloconfig/apollo","slug":"env-s-is-not-supported-emergency-publish-now","errorCode":null,"errorMessage":"Env: %s is not supported emergency publish now","messagePattern":"Env: (.+?) is not supported emergency publish now","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/NamespaceBranchController.java","lineNumber":261,"sourceCode":"  }\n\n  private boolean canDeleteBranch(String appId, String env, String clusterName,\n      String namespaceName, String branchName) {\n    boolean hasReleasePermission = unifiedPermissionValidator.hasReleaseNamespacePermission(appId,\n        env, clusterName, namespaceName);\n    boolean hasModifyPermission = unifiedPermissionValidator.hasModifyNamespacePermission(appId,\n        env, clusterName, namespaceName);\n    return hasReleasePermission || (hasModifyPermission && releaseService.loadLatestRelease(appId,\n        Env.valueOf(env), branchName, namespaceName) == null);\n  }\n\n  private void checkEmergencyPublishAllowedForUser(String env, boolean emergencyPublish) {\n    String authType = UserIdentityContextHolder.getAuthType();\n    if (emergencyPublish\n        && (UserIdentityConstants.USER.equals(authType)\n            || UserIdentityConstants.USER_TOKEN.equals(authType))\n        && !portalConfig.isEmergencyPublishAllowed(Env.valueOf(env))) {\n      throw new BadRequestException(\"Env: %s is not supported emergency publish now\", env);\n    }\n  }\n\n  private String resolveOperator(String queryOperator, String payloadOperator) {\n    String authType = UserIdentityContextHolder.getAuthType();\n    if (UserIdentityConstants.USER.equals(authType)\n        || UserIdentityConstants.USER_TOKEN.equals(authType)) {\n      UserInfo loginUser = userInfoHolder.getUser();\n      if (loginUser == null || StringUtils.isBlank(loginUser.getUserId())) {\n        throw new BadRequestException(\"Current user not found\");\n      }\n      return loginUser.getUserId();\n    }\n\n    if (UserIdentityConstants.CONSUMER.equals(authType)) {\n      String operator = StringUtils.isBlank(queryOperator) ? payloadOperator : queryOperator;\n      RequestPrecondition.checkArguments(!StringUtils.isContainEmpty(operator),\n          \"operator should not be null or empty\");","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/openapi/v1/controller/NamespaceBranchController.java#L243-L279","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nportalConfig.emergencyPublishAllowed = [DEV, FAT] // PROD not listed\nclient.publish(env=PROD, emergencyPublish=true); // 400\n\n// after: enable PROD in portal config\nportalConfig.emergencyPublishAllowed = [DEV, FAT, PRO]\n// or drop the flag\nclient.publish(env=PROD, emergencyPublish=false);","handlingStrategy":"validation","validationCode":"// Confirm emergency publish is allowed for the env before using the flag.\nboolean allowed = portalConfigEmergencyEnvs.contains(env); // from config endpoint/docs\nif (!allowed && emergencyPublish) {\n  // either drop the flag or request the env be added to the allow-list; do NOT call with flag=true\n}","typeGuard":"null","tryCatchPattern":"try {\n  client.publish(appId, env, cluster, ns, releaseDTO, /*emergencyPublish*/ true);\n} catch (HttpClientErrorException.BadRequest e) {\n  if (e.getMessage().contains(\"not supported emergency publish\")) {\n    // fall back to a normal publish, or have ops add the env to emergency allow-list\n  }\n}","preventionTips":["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."],"tags":["apollo-portal","openapi","emergency-publish","bad-request","config","environment"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}