How Maven Resumes Builds After Failure: The Complete Technical Guide

Maven resumes failed builds by persisting failure state to target/resume.properties and re-evaluating the reactor graph when invoked with --resume (-r), skipping modules that already succeeded.

When a multi-module build fails in the apache/maven repository, developers don't need to rebuild everything from scratch. The Maven build resumption mechanism records the exact failure point and provides intelligent shortcuts to restart from where the build broke. This feature is implemented across the core execution engine and involves state persistence, validation logic, and reactor graph manipulation.

Recording the Build Failure State

When Maven detects a build failure, it immediately serializes the current progress to disk. This creates a durable checkpoint that survives process termination.

The resume.properties File

Upon failure, Maven writes a resume.properties file to the root project's target directory. This file contains:

  • resumeFrom: The coordinates (groupId:artifactId) of the failed module
  • timestamp: The ISO-8601 timestamp when the failure occurred

If the build succeeds, Maven automatically removes this file to prevent stale resume attempts.

DefaultBuildResumptionDataRepository Implementation

The DefaultBuildResumptionDataRepository class in impl/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionDataRepository.java handles this persistence. Its store() method writes the properties file only when the build ends with failures, while successful builds trigger file deletion. The repository ensures the selector stored includes the groupId when necessary to resolve ambiguous artifact IDs.

Determining Resume Eligibility

Not every failed build can be resumed. Maven validates several preconditions before allowing the resume flag to take effect.

BuildResumptionAnalyzer Interface

The BuildResumptionAnalyzer interface in impl/maven-core/src/main/java/org/apache/maven/execution/BuildResumptionAnalyzer.java defines a single method that inspects MavenExecutionResult and returns an Optional<BuildResumptionData>. This abstraction allows the core to query whether resuming is technically possible before attempting graph manipulation.

Validation Logic in DefaultBuildResumptionAnalyzer

The DefaultBuildResumptionAnalyzer implementation performs strict validation in impl/maven-core/src/main/java/org/apache/maven/execution/DefaultBuildResumptionAnalyzer.java. It checks that:

  • The build actually failed
  • The resume.properties file exists and is readable
  • The execution involved a single reactor (multi-module builds only)
  • The failed project is not the first module in the reactor

If any check fails, it returns Optional.empty() and sets canResume() to false in the execution result.

Parsing the Resume Flag

User interaction with build resumption occurs through command-line options processed by the CLI layer.

CLI Option Processing

The MavenCli class in impl/maven-cli/src/main/java/org/apache/maven/cli/MavenCli.java parses --resume (-r) and --resume-from (-rf) via the CommonsCliMavenOptions class in impl/maven-cli/src/main/java/org/apache/maven/cli/CommonsCliMavenOptions.java. When detected, these flags populate the execution request with specific resume instructions.

MavenExecutionRequest Configuration

The MavenExecutionRequest interface and its implementation DefaultMavenExecutionRequest in impl/maven-core/src/main/java/org/apache/maven/execution/MavenExecutionRequest.java and impl/maven-core/src/main/java/org/apache/maven/execution/DefaultMavenExecutionRequest.java store two critical fields:

  • resume: Boolean flag indicating automatic resume mode
  • resumeFrom: Optional string selector specifying manual resume coordinates

When mvn -r executes, request.setResume(true) is invoked, signaling the core to look for the properties file.

Selecting the Resume Point

Once the resume flag is set, Maven must determine where in the reactor graph to begin execution.

Graph Building and Project Selection

The DefaultGraphBuilder in impl/maven-core/src/main/java/org/apache/maven/graph/DefaultGraphBuilder.java reads the selector from resume.properties when resume=true. It locates the index of the specified module in the sorted project list, then creates a sub-list containing only the projects from that index forward. This trims the reactor to exclude already-successful modules.

If the selector cannot be found, Maven aborts with the error: "Could not find project to resume reactor build from".

Handling Manual resume-from

When users specify --resume-from :module-name manually, the CLI sets request.setResumeFrom(":module-name"). This bypasses the properties file entirely. The graph builder validates this selector against the available projects, ensuring the resume target exists before constructing the partial reactor.

Executing the Partial Reactor

The actual execution of the trimmed module list occurs in the lifecycle engine.

The BuildPlanExecutor in impl/maven-core/src/main/java/org/apache/maven/lifecycle/internal/concurrent/BuildPlanExecutor.java receives the reduced project list and executes it exactly like a standard build. The executor logs diagnostic timing statistics under variables named resumed to track how much time was saved by skipping successful modules.

Edge Cases and Error Handling

Maven's resume logic handles several failure scenarios gracefully:

  • First module failure: No resume.properties is written because there are no successful modules to skip; canResume() returns false.
  • Multiple reactor execution: If the build involved multiple separate reactor executions, resume is disabled automatically.
  • Missing resume.properties: If the file is deleted or unreadable, Maven logs a warning and ignores the -r flag.
  • Ambiguous selectors: When artifact IDs collide across group IDs, Maven stores the full groupId:artifactId coordinate to ensure unique identification.
  • Invalid manual selectors: Attempting to resume from a non-existent module results in an immediate error before any build execution starts.

Practical Usage Examples

Below is the typical workflow for utilizing Maven build resumption.

First, run a build that fails in a multi-module project:

mvn clean install

# Build fails in module-b after module-a succeeds

Maven automatically creates target/resume.properties:

resumeFrom=com.example:module-b
timestamp=2026-07-05T14:23:12.345Z

Resume the build automatically:

mvn -r clean install

Or manually specify a resume point without the properties file:

mvn -rf :module-c clean install

Internally, this sets the resume parameters:

MavenExecutionRequest request = new DefaultMavenExecutionRequest();
request.setResume(true);           // From -r flag
request.setResumeFrom(null);       // Auto-detect from resume.properties

Summary

  • Maven build resumption persists failure state to target/resume.properties via DefaultBuildResumptionDataRepository.
  • The DefaultBuildResumptionAnalyzer validates that resuming is possible before allowing execution.
  • The MavenCli layer parses --resume (-r) and --resume-from (-rf) into MavenExecutionRequest flags.
  • DefaultGraphBuilder trims the reactor graph to exclude already-successful modules based on the stored selector.
  • BuildPlanExecutor runs the reduced build plan while logging resumed execution statistics.
  • Edge cases like first-module failures, missing files, and ambiguous selectors are handled with clear warnings or errors.

Frequently Asked Questions

What is the difference between --resume and --resume-from in Maven?

The --resume (-r) flag automatically reads the resume.properties file generated by a previous failed build and resumes from the exact failure point. The --resume-from (-rf) flag allows you to manually specify a module coordinate (like :module-name) to resume from, bypassing the automatic state detection. Use -r for automatic resumption after fixing the failure, and -rf when you want to start from a specific module regardless of previous state.

Where does Maven store the resume state?

Maven stores the resume state in a file named resume.properties located in the target directory of the root project. This file is written by DefaultBuildResumptionDataRepository only when a build fails, and it contains the resumeFrom selector (typically groupId:artifactId) and a timestamp. Successful builds automatically delete this file to prevent stale resumptions.

Can Maven resume a build if the first module fails?

No. Maven cannot resume a build if the first module in the reactor fails because there are no successful modules to skip. The DefaultBuildResumptionAnalyzer explicitly checks that the failed project is not the first one before writing resume.properties or allowing canResume() to return true. In this scenario, you must fix the issue and run the full build again.

How does Maven handle duplicate artifact IDs when resuming?

When multiple modules share the same artifact ID but different group IDs, Maven resolves the ambiguity by storing the full coordinate groupId:artifactId in the resumeFrom field of resume.properties. The DefaultBuildResumptionDataRepository enriches the selector with the group ID when necessary, ensuring that DefaultGraphBuilder can uniquely identify the correct module in the reactor graph.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →