{"record":{"id":"8432fe3e318b3ddf","repo":"apolloconfig/apollo","slug":"export-app-config-error","errorCode":null,"errorMessage":"export app config error","messagePattern":"export app config error","errorType":"exception","errorClass":"ServiceException","httpStatus":500,"severity":"error","filePath":"apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ConfigsExportService.java","lineNumber":136,"sourceCode":"    }\n    ClusterDTO cluster = clusterService.loadCluster(appId, env, clusterName);\n    if (cluster == null) {\n      throw new BadRequestException(\n          \"The app does not exist in the specified environment and cluster.\");\n    }\n\n    try (final ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {\n      try {\n        this.exportNamespaces(env, app, cluster, zipOutputStream, true);\n      } catch (BadRequestException badRequestException) {\n        // ignore\n      } catch (Exception e) {\n        logger.error(\"export namespace error. appId = {}, env = {}, cluster = {}\", app.getAppId(),\n            env.getName(), cluster.getName(), e);\n      }\n    } catch (IOException e) {\n      logger.error(\"export app config error\", e);\n      throw new ServiceException(\"export app config error\", e);\n    }\n  }\n\n  private void exportApps(final Collection<Env> exportEnvs, OutputStream outputStream) {\n    List<App> hasPermissionApps = findHasPermissionApps();\n\n    if (CollectionUtils.isEmpty(hasPermissionApps)) {\n      return;\n    }\n\n    try (final ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {\n      // write app info to zip\n      writeAppInfoToZip(hasPermissionApps, zipOutputStream);\n\n      // export app namespace\n      exportAppNamespaces(zipOutputStream);\n\n      // export app's clusters","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ConfigsExportService.java#L118-L154","documentation":"Thrown by ConfigsExportService.exportAppConfigByEnvAndCluster when an IOException occurs while writing the ZipOutputStream for a single-app export. The IOException is logged then re-thrown as a ServiceException (HTTP 500) wrapping the cause. Note inner BadRequestException/namespace errors are swallowed; only stream I/O failures escalate.","triggerScenarios":"The OutputStream backing the download is closed/broken mid-transfer, the client disconnects, disk/network sink fails, or the zip write hits an I/O error.","commonSituations":"Client cancels the download; servlet output stream aborted; disk full on a streamed temp path; network blip between portal and client during a large export.","solutions":["Ensure the client keeps the download stream open for the full transfer (avoid timeouts/cancellations).","Retry the export; transient I/O failures are not state-corrupting.","If reproducible, check portal disk space / network egress and the size of the exported namespace set.","Reduce export scope (narrow namespaces) if the zip is extremely large."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { exportAppConfigByEnvAndCluster(appId, env, cluster, out); }\ncatch (ServiceException e) { log.warn(\"single-app export failed: {}\", e.getMessage()); /* retry or narrow scope */ }","preventionTips":["Keep the download stream open for the full transfer.","Retry transient I/O failures; they do not corrupt state.","Narrow the export scope if the zip is very large."],"tags":["apollo-portal","config-export","io","service-exception","zip"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}