apache/kafka · error · IllegalArgumentException
At least one valid string must be provided when empty values
Error message
At least one valid string must be provided when empty values are not allowed
What it means
Thrown by the ValidList.in(boolean isEmptyAllowed, String...) static factory when isEmptyAllowed is false but no validStrings were supplied. ValidList is a Validator that restricts a LIST-typed config to a fixed set of allowed values; disallowing empty lists while providing no allowed values is contradictory (every list would be invalid), so the factory refuses to build the Validator. This is a developer/config-author error in ConfigDef construction, not a runtime config-value error.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java:1052
final boolean isNullAllowed;
private ValidList(List<String> validStrings, boolean isEmptyAllowed, boolean isNullAllowed) {
this.validString = new ValidString(validStrings);
this.isEmptyAllowed = isEmptyAllowed;
this.isNullAllowed = isNullAllowed;
}
public static ValidList anyNonDuplicateValues(boolean isEmptyAllowed, boolean isNullAllowed) {
return new ValidList(List.of(), isEmptyAllowed, isNullAllowed);
}
public static ValidList in(String... validStrings) {
return new ValidList(List.of(validStrings), true, false);
}
public static ValidList in(boolean isEmptyAllowed, String... validStrings) {
if (!isEmptyAllowed && validStrings.length == 0) {
throw new IllegalArgumentException("At least one valid string must be provided when empty values are not allowed");
}
return new ValidList(List.of(validStrings), isEmptyAllowed, false);
}
@Override
public void ensureValid(final String name, final Object value) {
if (value == null) {
if (isNullAllowed)
return;
else
throw new ConfigException("Configuration '" + name + "' values must not be null.");
}
@SuppressWarnings("unchecked")
List<Object> values = (List<Object>) value;
if (!isEmptyAllowed && values.isEmpty()) {
String validString = this.validString.validStrings.isEmpty() ? "any non-empty value" : this.validString.toString();
throw new ConfigException("Configuration '" + name + "' must not be empty. Valid values include: " + validString);View on GitHub (pinned to c31c9215e1)
Solutions
- Pass at least one allowed value: ValidList.in(false, "a","b").
- Or allow empty lists: ValidList.in(true).
- If the allowed set is computed dynamically, guard the call: if (allowed.isEmpty()) ValidList.in(true) else ValidList.in(false, allowed.toArray).
- Fail loudly at construction with a meaningful message rather than silently building an all-rejecting validator.
Example fix
// before
String[] allowed = discoverAllowedValues(); // returns empty
Validator v = ConfigDef.ValidList.in(false, allowed);
// -> IllegalArgumentException
// after
Validator v = allowed.length == 0
? ConfigDef.ValidList.in(true)
: ConfigDef.ValidList.in(false, allowed); Defensive patterns
Strategy: validation
Validate before calling
if (!isEmptyAllowed && validStrings.length == 0) {
throw new IllegalArgumentException(
"Supply at least one valid string, or set isEmptyAllowed=true");
}
ConfigDef.ValidList.in(isEmptyAllowed, validStrings); Type guard
public static boolean isValidListArgs(boolean isEmptyAllowed, String[] validStrings) {
return isEmptyAllowed || (validStrings != null && validStrings.length > 0);
} Try / catch
try {
ConfigDef.ValidList.in(isEmptyAllowed, validStrings);
} catch (IllegalArgumentException e) {
if (e.getMessage().equals("At least one valid string must be provided when empty values are not allowed")) {
// either pass at least one allowed string, or set isEmptyAllowed=true
} else throw e;
} Prevention
- When building a ValidList with isEmptyAllowed=false, always supply a non-empty allow-list.
- Treat an empty allow-list combined with isEmptyAllowed=false as a programmer error, not a runtime condition.
- Add a unit test that asserts your config builder calls never produce this combination.
When it happens
Trigger: Calling ConfigDef.ValidList.in(false) or ConfigDef.ValidList.in(false, new String[0]) when building a custom ConfigDef — typically a custom Kafka Connect connector, a custom Streams config, or a broker plugin that defines its own enum-like LIST config. The factory throws IllegalArgumentException at ConfigDef build time, before any client is started.
Common situations: Custom connector author wires ValidList.in(false, allowedArray) where allowedArray is computed at runtime (e.g. from config or service discovery) and ends up empty; refactoring that moves the allowed-values list into a separate method that returns empty under some condition; copy-paste of a ValidString.in pattern into ValidList without supplying values; conditional config that builds the validator only when a feature flag is off.
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
- Illegal MetadataRecoveryStrategy: null
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/f166f8a86436b240.json.
Report an issue: GitHub.