quarkusio/quarkus · error · RuntimeException

Failed to read ${compareFile}

Error message

Failed to read ${compareFile}

What it means

TrackConfigChangesMojo (used by quarkus:dev config-change tracking) reloads the previously saved configuration snapshot (the -config-check properties file) to compare against the current config. If reading that file throws IOException, it wraps it in RuntimeException 'Failed to read <compareFile>'. This means the stored previous-config file exists but cannot be parsed/read.

Source

Thrown at devtools/maven/src/main/java/io/quarkus/maven/TrackConfigChangesMojo.java:124

        if (!prevConfigExists && !dumpCurrentWhenRecordedUnavailable && !dumpDependencies) {
            getLog().info("Config dump from the previous build does not exist at " + compareFile);
            return;
        }

        CuratedApplication curatedApplication = null;
        QuarkusClassLoader deploymentClassLoader = null;
        final ClassLoader originalCl = Thread.currentThread().getContextClassLoader();
        final boolean clearNativeEnabledSystemProperty = setNativeEnabledIfNativeProfileEnabled();
        try {
            curatedApplication = bootstrapApplication(launchMode);
            if (prevConfigExists || dumpCurrentWhenRecordedUnavailable) {
                final Path targetFile = getOutputFile(outputFile, launchMode.getDefaultProfile(), "-config-check");
                Properties compareProps = new Properties();
                if (prevConfigExists) {
                    try (BufferedReader reader = Files.newBufferedReader(compareFile)) {
                        compareProps.load(reader);
                    } catch (IOException e) {
                        throw new RuntimeException("Failed to read " + compareFile, e);
                    }
                }

                deploymentClassLoader = curatedApplication.createDeploymentClassLoader();
                Thread.currentThread().setContextClassLoader(deploymentClassLoader);

                final Class<?> codeGenerator = deploymentClassLoader.loadClass("io.quarkus.deployment.CodeGenerator");
                final Method dumpConfig = codeGenerator.getMethod("dumpCurrentConfigValues", ApplicationModel.class,
                        String.class,
                        Properties.class, QuarkusClassLoader.class, Properties.class, Path.class);
                dumpConfig.invoke(null, curatedApplication.getApplicationModel(),
                        launchMode.name(), getBuildSystemProperties(true),
                        deploymentClassLoader, compareProps, targetFile);
            }

            if (dumpDependencies) {
                final List<Path> deps = new ArrayList<>();
                for (var d : curatedApplication.getApplicationModel().getDependencies(DependencyFlags.DEPLOYMENT_CP)) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Delete the stale file (target/-config-check snapshot in target/) and restart dev mode so it is regenerated
  2. Fix permissions/ownership on the target/ directory
  3. Run `mvn clean` to remove corrupted build state, then rebuild
  4. Exclude target/ from container volume mounts or sync tools that break file consistency

Example fix

// recovery
rm -f target/*-config-check*
mvn clean quarkus:dev
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the snapshot file is readable and non-truncated before dev runs:
Path f = Paths.get("target").resolve("dev-config-check.properties");
if (Files.exists(f) && (!Files.isReadable(f) || Files.size(f) == 0)) Files.delete(f);

Try / catch

catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Failed to read")) {
    Files.deleteIfExists(staleSnapshotPath); // regenerate on next run
    restartDevMode();
  } else throw e;
}

Prevention

When it happens

Trigger: Prev config file exists (prevConfigExists==true) but Files.newBufferedReader or properties.load fails: corrupted/partial file from a crashed previous run, permission changes, or the file was deleted between the exists() check and the read (TOCTOU race).

Common situations: Killed dev process leaving a truncated config-check file; read-only target/ after copying workspaces between users/containers; target/ synced with different ownership (docker volume UID mismatch); antivirus holding the file.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/6005337adb23d338. Report an issue: GitHub.