spring-projects/spring-boot · error · InvalidUserDataException

Invalid value for option '--environment'. Expected 'NAME=VAL

Error message

Invalid value for option '--environment'. Expected 'NAME=VALUE' but got '{}'.

What it means

Thrown by BootBuildImage.asMap() while parsing values passed via the --environment command-line option (getEnvironmentFromCommandLine). Each value must be NAME=VALUE; if there is no '=' or it appears at index 0 (empty name), an InvalidUserDataException is raised. The check is indexOf('=') <= 0.

Source

Thrown at build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java:119

		getCleanCache().convention(false);
		getVerboseLogging().convention(false);
		getPublish().convention(false);
		this.buildWorkspace = getProject().getObjects().newInstance(LocalCacheSpec.class);
		this.buildCache = getProject().getObjects().newInstance(CacheSpec.class);
		this.launchCache = getProject().getObjects().newInstance(LocalCacheSpec.class);
		this.docker = getProject().getObjects().newInstance(DockerSpec.class);
		this.pullPolicy = getProject().getObjects().property(PullPolicy.class);
		getSecurityOptions().convention((Iterable<? extends String>) null);
		getEffectiveEnvironment().putAll(getEnvironment());
		getEffectiveEnvironment().putAll(getEnvironmentFromCommandLine().map(BootBuildImage::asMap));
	}

	private static Map<String, String> asMap(List<String> variables) {
		Map<String, String> environment = new LinkedHashMap<>();
		for (String variable : variables) {
			int index = variable.indexOf('=');
			if (index <= 0) {
				throw new InvalidUserDataException(
						"Invalid value for option '--environment'. Expected 'NAME=VALUE' but got '" + variable + "'.");
			}
			String name = variable.substring(0, index);
			String value = variable.substring(index + 1);
			environment.put(name, value);
		}
		return environment;
	}

	/**
	 * Returns the property for the archive file from which the image will be built.
	 * @return the archive file property
	 */
	@InputFile
	@PathSensitive(PathSensitivity.RELATIVE)
	public abstract RegularFileProperty getArchiveFile();

	/**

View on GitHub (pinned to 5b2dbdbb8b)

Solutions

  1. Provide the value as NAME=VALUE, e.g. ./gradlew bootBuildImage --environment=BP_JVM_VERSION=21.
  2. If the value may be empty, still include the '=': --environment=BP_DEBUG_ENABLED=.
  3. Quote the whole token in shell to prevent splitting: --environment="BP_DEBUG_ENABLED=true".
  4. For multiple variables, repeat the flag once per NAME=VALUE pair.

Example fix

// before:
//   ./gradlew bootBuildImage --environment=BP_JVM_VERSION 21
// after:
//   ./gradlew bootBuildImage --environment=BP_JVM_VERSION=21
Defensive patterns

Strategy: validation

Validate before calling

fun isValidEnvToken(token: String): Boolean {
    val idx = token.indexOf('=')
    return idx > 0 && token.substring(0, idx).isNotEmpty()
}

val tokens = listOf("BP_JVM_VERSION=21")
require(tokens.all { isValidEnvToken(it) }) {
    "All --environment values must be NAME=VALUE"
}

Prevention

When it happens

Trigger: Invoking bootBuildImage (or bootBuildImagePoll) with --environment FOO or --environment =VALUE (or any token where '=' is missing or at position 0) hits the failing branch at line 119.

Common situations: Typos in CLI args (missing '='), copy-paste of 'FOO BAR', shell-quoting that strips '=', passing a bare variable name, or scripts that build the flag dynamically without the separator.

Related errors


AI-assisted analysis of spring-projects/spring-boot@5b2dbdbb8b (2026-08-04). Data as JSON: /data/errors/b24ccb1544026874.json. Report an issue: GitHub.