apache/kafka · error · ConfigException

String must be one of: String.join(", ", validStrings)

Error message

String must be one of: String.join(", ", validStrings)

What it means

Thrown by ValidString.ensureValid when the supplied string is not a member of the validator's enumerated validStrings list (case-sensitive exact match via List.contains). ConfigDef uses ValidString.in(...) to constrain a config to a closed set of allowed values (e.g. an enum-like option); the message lists every permitted value to aid correction.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java:1116

        }
    }

    public static class ValidString implements Validator {
        final List<String> validStrings;

        private ValidString(List<String> validStrings) {
            this.validStrings = validStrings;
        }

        public static ValidString in(String... validStrings) {
            return new ValidString(Arrays.asList(validStrings));
        }

        @Override
        public void ensureValid(String name, Object o) {
            String s = (String) o;
            if (!validStrings.contains(s)) {
                throw new ConfigException(name, o, "String must be one of: " + String.join(", ", validStrings));
            }

        }

        public String toString() {
            return "[" + String.join(", ", validStrings) + "]";
        }
    }

    public static class CaseInsensitiveValidString implements Validator {

        final Set<String> validStrings;

        private CaseInsensitiveValidString(List<String> validStrings) {
            this.validStrings = validStrings.stream()
                .map(s -> s.toUpperCase(Locale.ROOT))
                .collect(Collectors.toSet());
        }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Set the config to one of the values literally printed in the message, observing exact case.
  2. If you need case-insensitive matching, change the ConfigKey validator to CaseInsensitiveValidString.in(...) (requires the config's owner module to support it).
  3. Check the Kafka version of your client/broker docs for the canonical list of allowed values — the set may differ across versions.

Example fix

// before
props.put("security.protocol", "TLS");  // not in valid set

// after
props.put("security.protocol", "SSL");
Defensive patterns

Strategy: validation

Validate before calling

// Validate against the same allow-list Kafka's ValidString uses:
Set<String> allowed = Set.of("PLAIN", "SCRAM-SHA-512", "GSSAPI", "OAUTHBEARER"); // example: sasl.mechanism
String val = (String) configs.getOrDefault("sasl.mechanism", "");
if (!allowed.contains(val)) {
    throw new IllegalArgumentException("sasl.mechanism must be one of " + allowed + " but was '" + val + "'");
}

Type guard

// Narrow to a known enum-like constant at the boundary:
enum SaslMechanism { PLAIN, SCRAM_SHA_512, GSSAPI, OAUTHBEARER; }

Try / catch

try {
    def.parse(props);
} catch (ConfigException ce) {
    if (ce.getMessage().startsWith("String must be one of:")) {
        log.error("Config '{}' has illegal value '{}'. Allowed: {}",
                  ce.getName(), ce.value(), ce.getMessage());
        promptOperatorFor(ce.getName());
    } else throw ce;
}

Prevention

When it happens

Trigger: A ConfigKey validated with ValidString.in("read","write","admin") is given a value not in that set, e.g. "READ" (wrong case) or "superuser". Triggered during ConfigDef.parse()/validate() when the validator's ensureValid runs.

Common situations: Wrong casing of an allowed value ("READ" vs "read"), typo in the config, using a value valid in an older/newer Kafka version that has since been renamed or removed, or copy-pasting a value from documentation for a different component.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/642d53e9b21a1585.json. Report an issue: GitHub.