{"record":{"id":"103b9018caaace26","repo":"apolloconfig/apollo","slug":"export-config-error","errorCode":null,"errorMessage":"export config error","messagePattern":"export 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":164,"sourceCode":"\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\n      exportEnvs.parallelStream().forEach(env -> {\n        try {\n          this.exportClusters(env, hasPermissionApps, zipOutputStream);\n        } catch (Exception e) {\n          logger.error(\"export cluster error. env = {}\", env, e);\n        }\n      });\n    } catch (IOException e) {\n      logger.error(\"export config error\", e);\n      throw new ServiceException(\"export config error\", e);\n    }\n  }\n\n  private List<App> findHasPermissionApps() {\n    // get all apps\n    final List<App> apps = appService.findAll();\n\n    if (CollectionUtils.isEmpty(apps)) {\n      return Collections.emptyList();\n    }\n\n    // permission check\n    final Predicate<App> isAppAdmin = app -> {\n      try {\n        return unifiedPermissionValidator.isAppAdmin(app.getAppId());\n      } catch (Exception e) {\n        logger.error(\"permission check failed. app = {}\", app);\n        return false;","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ConfigsExportService.java#L146-L182","documentation":"Thrown by ConfigsExportService.exportApps (bulk export of all permitted apps) when an IOException occurs while writing the top-level ZipOutputStream. The IOException is logged then re-thrown as ServiceException (HTTP 500). Per-env cluster export errors are caught and logged inside the stream and do NOT propagate; only the outer zip I/O failure escalates.","triggerScenarios":"Bulk export (all apps the user has permission to) where the OutputStream fails during the multi-env write, or the client disconnects during a large aggregate download.","commonSituations":"Large fleet export timing out the HTTP connection; client cancellation; parallel exportEnvs.stream() consuming resources; network/disk sink failure mid-export.","solutions":["Keep the client connection alive for the full bulk export; raise HTTP timeout if the fleet is large.","Scope the export to fewer apps/envs to reduce transfer size and duration.","Retry on transient I/O; this path does not corrupt portal state.","Check portal/network capacity if the failure is reproducible."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { exportApps(envs, out); }\ncatch (ServiceException e) { log.warn(\"bulk export failed: {}\", e.getMessage()); /* retry with smaller scope */ }","preventionTips":["Increase HTTP timeout / keep connection alive for large bulk exports.","Scope bulk exports to fewer apps/envs to reduce duration.","Retry transient I/O failures."],"tags":["apollo-portal","config-export","io","service-exception","bulk-export"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}