apache/kafka · error · IllegalArgumentException
Illegal MetadataRecoveryStrategy: null
Error message
Illegal MetadataRecoveryStrategy: null
What it means
IllegalArgumentException thrown by MetadataRecoveryStrategy.forName when the supplied strategy name is null. The enum has only two valid names ('none', 'rebootstrap'); a null name cannot be matched, so the constructor refuses it before valueOf is even attempted. It protects NetworkClient initialisation (which reads metadata.recovery.strategy) from an undefined recovery mode.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/MetadataRecoveryStrategy.java:36
import java.util.Locale;
/**
* Defines the strategies which clients can follow to deal with the situation when none of the known nodes is available.
*/
public enum MetadataRecoveryStrategy {
NONE("none"),
REBOOTSTRAP("rebootstrap");
public final String name;
MetadataRecoveryStrategy(String name) {
this.name = name;
}
public static MetadataRecoveryStrategy forName(String name) {
if (name == null) {
throw new IllegalArgumentException("Illegal MetadataRecoveryStrategy: null");
}
try {
return MetadataRecoveryStrategy.valueOf(name.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Illegal MetadataRecoveryStrategy: " + name);
}
}
}
View on GitHub (pinned to c31c9215e1)
Solutions
- Set metadata.recovery.strategy to one of the documented values: 'none' (default) or 'rebootstrap'.
- If building configs in code, ensure the value is non-null before passing to the client (filter out nulls).
- If the value is optional in your config layer, default it to 'none' rather than letting null propagate.
Example fix
// before
props.put("metadata.recovery.strategy", null); // NPE-prone, later throws
// after
props.put("metadata.recovery.strategy", "none"); Defensive patterns
Strategy: type-guard
Validate before calling
// metadata.recovery.strategy config must be "none" or "rebootstrap"
// (case-insensitive). Pre-validate the config string:
import java.util.Locale;
import java.util.Set;
static final Set<String> VALID = Set.of("none", "rebootstrap");
static String normalizeRecoveryStrategy(String raw) {
if (raw == null)
throw new IllegalArgumentException(
"metadata.recovery.strategy is null; expected one of " + VALID);
String norm = raw.trim().toLowerCase(Locale.ROOT);
if (!VALID.contains(norm))
throw new IllegalArgumentException(
"metadata.recovery.strategy='" + raw + "' is not in " + VALID);
return norm;
}
// props.put("metadata.recovery.strategy", normalizeRecoveryStrategy(raw)); Type guard
static boolean isValidRecoveryStrategy(String raw) {
if (raw == null) return false;
String n = raw.trim().toLowerCase(Locale.ROOT);
return n.equals("none") || n.equals("rebootstrap");
} Try / catch
// Thrown by MetadataRecoveryStrategy.forName during client construction.
try {
admin = AdminClient.create(props);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Illegal MetadataRecoveryStrategy")) {
// Strip the bad value and let the client fall back to its default
// (DEFAULT_METADATA_RECOVERY_STRATEGY == REBOOTSTRAP), or fail loud:
props.remove("metadata.recovery.strategy");
// then decide: retry once without it, or surface to the operator.
throw new ConfigurationException(e.getMessage(), e);
}
throw e;
} Prevention
- Do not invent strategy names — only "none" and "rebootstrap" exist; future values come from new Kafka releases, so validate against the enum, not a hard-coded copy.
- Default the config in your application's own defaults file rather than relying on the operator to type it correctly.
- If you expose this setting via an env var or secrets manager, validate it at config-load time and fail fast with a clear message.
- Remember that strategy=none disables recovery entirely — a client that loses all brokers will stay broken until restarted.
When it happens
Trigger: Setting 'metadata.recovery.strategy' to null, an empty string is not null but a genuinely null config value (e.g. programmatic Map.put(key, null)), or calling forName(null) directly. Reached via ClientUtils.createNetworkClient when building the NetworkClient.
Common situations: Programmatically building configs with a null value, a properties file with the key present but unassigned being parsed as null, a custom config provider returning null, or test code passing null instead of the string literal 'none'.
Related errors
- Invalid url in bootstrap.servers: {url}
- Invalid url in bootstrap.servers: {url}
- Invalid port in bootstrap.servers: {url}
- When the security.protocol configuration enables SASL, mecha
- Invalid leader epoch {leaderEpoch} (must be non-negative)
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/32d0abf795e14558.json.
Report an issue: GitHub.