jenkinsci/jenkins · error · IllegalArgumentException
Null value not allowed as an environment variable: ${key}
Error message
Null value not allowed as an environment variable: ${key} What it means
EnvVars overrides Map.put to reject null values with IllegalArgumentException because environment variables cannot represent null. This enforces a hard invariant at the boundary rather than letting a null silently propagate into process spawning or serialization. Use putIfNotNull or putAllNonNull when null is a legitimate 'absent' signal.
Source
Thrown at core/src/main/java/hudson/EnvVars.java:379
public static void resolve(Map<String, String> env) {
for (Map.Entry<String, String> entry : env.entrySet()) {
entry.setValue(Util.replaceMacro(entry.getValue(), env));
}
}
/**
* Convenience message
* @since 1.485
**/
public String get(String key, String defaultValue) {
String v = get(key);
if (v == null) v = defaultValue;
return v;
}
@Override
public String put(String key, String value) {
if (value == null) throw new IllegalArgumentException("Null value not allowed as an environment variable: " + key);
return super.put(key, value);
}
/**
* Add a key/value but only if the value is not-null. Otherwise no-op.
* @since 1.556
*/
public void putIfNotNull(String key, String value) {
if (value != null)
put(key, value);
}
/**
* Add entire map but filter null values out.
* @since 2.214
*/
public void putAllNonNull(Map<String, String> map) {
map.forEach(this::putIfNotNull);View on GitHub (pinned to 2e228ff40b)
Solutions
- Replace put with putIfNotNull when a null should be a no-op.
- Use putAllNonNull when bulk-merging a map that may contain nulls.
- Sanitize the source value: substitute an empty string or a default before put.
- If using addLine, guard against empty values before calling put.
Example fix
// before
envVars.put("PATH", System.getenv("MISSING")); // null -> throws
// after
envVars.putIfNotNull("PATH", System.getenv("MISSING")); Defensive patterns
Strategy: validation
Validate before calling
if (value != null) {
envVars.put(key, value);
} else {
// decide policy: skip, or put empty string
} Type guard
static boolean isSettableEnvValue(String v) { return v != null; } Try / catch
try {
envVars.put(key, value);
} catch (IllegalArgumentException e) {
// 'Null value not allowed' — fall back to a safe default or skip
envVars.putIfNotNull(key, value);
} Prevention
- Prefer putIfNotNull / putAllNonNull when merging maps that may contain nulls.
- Sanitize values from expand()/getenv() before put, since unresolved macros yield null.
- Add a unit test asserting no null values reach EnvVars.
When it happens
Trigger: Calling envVars.put("KEY", null); passing a map value that resolved to null (e.g., via expand/replaceMacro that left a variable unresolved); merging an external map that contains null values; addLine on a malformed 'KEY=' line.
Common situations: Reading env from a map that may hold nulls; expanding ${VAR} where VAR is unset returns null; config-provided environment block with an empty value; JDK code path calling putAll with a map containing nulls.
Related errors
- invalid iconSize
- Ambiguous plugin: {0}
- No such plugin: {0}
- {0} is not a Jenkins plugin
- Malformed plugin attribute: {0}
AI-assisted analysis of jenkinsci/jenkins@2e228ff40b (2026-08-14).
Data as JSON: /api/errors/ccd84c9ff8edcbc6.
Report an issue: GitHub.