apolloconfig/apollo · error · ServiceException

Read config file errors:{}

Error message

Read config file errors:{}

What it means

Thrown by ConfigsImportService.forceImportNamespaceFromFile() when reading the provided InputStream into a String via ConfigToFileUtils.fileToString() fails with an IOException. This is the first step of a forced namespace import — the uploaded file content cannot be read, so the import aborts before any parsing or application.

Source

Thrown at apollo-portal/src/main/java/com/ctrip/framework/apollo/portal/service/ConfigsImportService.java:96

    this.itemService = itemService;
    this.appService = appService;
    this.clusterService = clusterService;
    this.namespaceService = namespaceService;
    this.appNamespaceService = appNamespaceService;
    this.publisher = publisher;
    this.roleInitializationService = roleInitializationService;
  }

  /**
   * force import, new items will overwrite existed items.
   */
  public void forceImportNamespaceFromFile(final Env env, final String standardFilename,
      final InputStream zipInputStream, String operator) {
    String configText;
    try (InputStream in = zipInputStream) {
      configText = ConfigToFileUtils.fileToString(in);
    } catch (IOException e) {
      throw new ServiceException("Read config file errors:{}", e);
    }

    this.importNamespaceFromText(env, standardFilename, configText, false, operator);
  }

  /**
   * import all data include app、appnamespace、cluster、namespace、item
   */
  public void importDataFromZipFile(List<Env> importEnvs, ZipInputStream dataZip,
      boolean ignoreConflictNamespace, String operator) throws IOException {
    List<String> toImportApps = Lists.newArrayList();
    List<String> toImportAppNSs = Lists.newArrayList();
    List<ImportClusterData> toImportClusters = Lists.newArrayList();
    List<ImportNamespaceData> toImportNSs = Lists.newArrayList();

    ZipEntry entry;
    while ((entry = dataZip.getNextEntry()) != null) {
      if (entry.isDirectory()) {

View on GitHub (pinned to d95fc18d11)

Solutions

  1. Verify the uploaded file is valid and non-empty before calling the import API.
  2. Ensure the InputStream is not consumed or closed before being passed to forceImportNamespaceFromFile.
  3. Check the file encoding matches what ConfigToFileUtils.fileToString() expects.
  4. Inspect portal logs for the underlying IOException cause to distinguish corruption from encoding issues.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the input stream before import
if (zipInputStream == null || zipInputStream.available() == 0) {
  throw new IllegalArgumentException("Input stream is null or empty");
}
byte[] bytes = zipInputStream.readAllBytes();
if (bytes.length == 0) {
  throw new IllegalArgumentException("Config file content is empty");
}
String configText = new String(bytes, StandardCharsets.UTF_8);

Try / catch

try {
  configsImportService.forceImportNamespaceFromFile(env, filename, inputStream, operator);
} catch (ServiceException e) {
  if (e.getMessage().contains("Read config file errors")) {
    log.error("Failed to read uploaded config file", e);
    // prompt user to re-upload a valid file
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling forceImportNamespaceFromFile with a corrupted, empty, or prematurely-closed InputStream. The try-with-resources closes the stream, and any read failure (malformed bytes, broken upload, stream already consumed) surfaces as ServiceException.

Common situations: Upload of a malformed or truncated config file; multipart upload where the InputStream was already consumed by another reader; character encoding mismatch causing read failure; network interruption during file upload.

Related errors


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