spring-projects/spring-boot · error · MojoFailureException

Failed to generate build-info.properties. {ex.getMessage()}

Error message

Failed to generate build-info.properties. {ex.getMessage()}

What it means

MojoFailureException (a build-logic failure, not infrastructure) thrown by BuildInfoMojo.execute when BuildPropertiesWriter rejects a null additional property value via NullAdditionalPropertyValueException. The message includes the underlying exception's text, so the offending property name is visible. Other exceptions fall through to a generic MojoExecutionException in the next catch.

Source

Thrown at build-plugin/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/BuildInfoMojo.java:128

	@Inject
	public BuildInfoMojo(BuildContext buildContext) {
		this.buildContext = buildContext;
	}

	@Override
	public void execute() throws MojoExecutionException, MojoFailureException {
		if (this.skip) {
			getLog().debug("skipping build-info as per configuration.");
			return;
		}
		try {
			ProjectDetails details = getProjectDetails();
			new BuildPropertiesWriter(this.outputFile).writeBuildProperties(details);
			this.buildContext.refresh(this.outputFile);
		}
		catch (NullAdditionalPropertyValueException ex) {
			throw new MojoFailureException("Failed to generate build-info.properties. " + ex.getMessage(), ex);
		}
		catch (Exception ex) {
			throw new MojoExecutionException(ex.getMessage(), ex);
		}
	}

	private ProjectDetails getProjectDetails() {
		String group = getIfNotExcluded("group", this.project.getGroupId());
		String artifact = getIfNotExcluded("artifact", this.project.getArtifactId());
		String version = getIfNotExcluded("version", this.project.getVersion());
		String name = getIfNotExcluded("name", this.project.getName());
		Instant time = getIfNotExcluded("time", getBuildTime());
		Map<String, String> additionalProperties = applyExclusions(this.additionalProperties);
		return new ProjectDetails(group, artifact, version, name, time, additionalProperties);
	}

	private <T> @Nullable T getIfNotExcluded(String name, @Nullable T value) {
		return (this.excludeInfoProperties == null || !this.excludeInfoProperties.contains(name)) ? value : null;

View on GitHub (pinned to 270dfe353f)

Solutions

  1. Read ex.getMessage() — it names the property whose value is null.
  2. Provide a default: ${env.UNSET_VAR:-default} (via a properties plugin) or set the environment variable in CI.
  3. Activate the profile that defines the property, or remove the entry if the value is optional.
  4. Run with -X to see the resolved property values during build-info.

Example fix

// before: <additionalProperties><scmRevision>${env.GIT_COMMIT}</scmRevision></additionalProperties>   (env var unset)
// after:  <scmRevision>${git.commit.id}</scmRevision>   (via git-commit-id-plugin, always populated)
Defensive patterns

Strategy: validation

Validate before calling

// Resolve every <additionalProperties> value to non-null before the goal:
Map<String,String> additional = /* from config */;
for (Map.Entry<String,String> e : additional.entrySet()) {
    if (e.getValue() == null) {
        throw new IllegalArgumentException("build-info additional property '" + e.getKey() + "' resolved to null");
    }
}

Try / catch

try {
    // invoke build-info
} catch (MojoFailureException ex) { // MojoFailureException, not MojoExecutionException
    if (ex.getMessage().startsWith("Failed to generate build-info.properties")) {
        // a null additional property — read ex.getMessage() for the name
    }
    throw ex;
}

Prevention

When it happens

Trigger: Declaring <additionalProperties> with a value that resolves to null, e.g. referencing a missing Maven property, a ${...} that doesn't exist, or programmatically injecting null. BuildPropertiesWriter throws NullAdditionalPropertyValueException to refuse emitting an incomplete build-info.properties.

Common situations: Using <additionalProperties><property>${env.UNSET_VAR}</property></additionalProperties> with an unset environment variable; referencing a property only defined in a profile that isn't active; CI environment missing a variable that's set locally.

Related errors


AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11). Data as JSON: /api/errors/f7b041d57b26f916. Report an issue: GitHub.