apache/kafka · error · org.apache.kafka.common.config.ConfigException
Invalid value `{}` for configuration {}. The value must be e
Error message
Invalid value `{}` for configuration {}. The value must be either 'earliest', 'latest', 'none' or of the format 'by_duration:<PnDTnHnMn.nS.>'. What it means
Thrown by AutoOffsetResetStrategy.Validator.ensureValid when the configured value for auto.offset.reset (or equivalent) cannot be parsed into one of the accepted strategies. The validator calls AutoOffsetResetStrategy.fromString, which accepts the literal strings 'earliest', 'latest', 'none', or 'by_duration:' followed by a valid ISO-8601 duration (PnDTnHnMn.nS). Any other value (typo, wrong case, malformed duration, negative duration, or the bare 'by_duration' without a duration suffix) is rejected and wrapped into a ConfigException at validation time, before the consumer is constructed.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/AutoOffsetResetStrategy.java:165
return Objects.hash(type, duration);
}
@Override
public String toString() {
return "AutoOffsetResetStrategy{" +
"type=" + type +
(duration.map(value -> ", duration=" + value).orElse("")) +
'}';
}
public static class Validator implements ConfigDef.Validator {
@Override
public void ensureValid(String name, Object value) {
String offsetStrategy = (String) value;
try {
fromString(offsetStrategy);
} catch (Exception e) {
throw new ConfigException(name, value, "Invalid value `" + offsetStrategy + "` for configuration " +
name + ". The value must be either 'earliest', 'latest', 'none' or of the format 'by_duration:<PnDTnHnMn.nS.>'.");
}
}
@Override
public String toString() {
String values = Arrays.stream(StrategyType.values())
.map(strategyType -> {
if (strategyType == StrategyType.BY_DURATION) {
return "by_duration:PnDTnHnMn.nS";
}
return strategyType.toString();
}).collect(Collectors.joining(", "));
return "[" + values + "]";
}
}
}
View on GitHub (pinned to c31c9215e1)
Solutions
- Set auto.offset.reset to one of the exact literals 'earliest', 'latest', or 'none' (lowercase, no whitespace).
- If you want a by-duration reset, use the exact format 'by_duration:PnDTnHnMn.nS' (e.g. 'by_duration:PT5M', 'by_duration:P1DT2H').
- Trim any trailing/leading whitespace and confirm casing in your config source (properties file, env var, command line).
- Verify you are running a client version that supports by_duration if you intend to use it; older clients only accept earliest/latest/none.
Example fix
// before props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "lastest"); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "by_duration:5m"); // after props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "latest"); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "by_duration:PT5M");
Defensive patterns
Strategy: validation
Validate before calling
// Validate auto.offset.reset before building the consumer
import java.time.Duration;
import java.util.Locale;
import java.util.Set;
import java.util.regex.Pattern;
private static final Set<String> NAMED = Set.of("earliest", "latest", "none");
// ISO-8601 duration, e.g. P1DT2H3M4.5S (must be non-negative)
private static final Pattern ISO_DURATION =
Pattern.compile("^P(?!$)(\\d+Y)?(\\d+M)?(\\d+W)?(\\d+D)?(T(?=.*\\d)(\\d+H)?(\\d+M)?(\\d+(\\.\\d+)?S)?)?$");
static String normalizeAutoOffsetReset(String raw) {
if (raw == null) throw new IllegalArgumentException("auto.offset.reset is null");
String v = raw.trim().toLowerCase(Locale.ROOT);
if (NAMED.contains(v)) return v;
if (v.startsWith("by_duration:")) {
String iso = v.substring("by_duration:".length());
if (!ISO_DURATION.matcher(iso).matches())
throw new IllegalArgumentException("Malformed ISO-8601 duration: " + iso);
Duration d = Duration.parse(iso);
if (d.isNegative())
throw new IllegalArgumentException("Duration must be non-negative: " + d);
return v;
}
throw new IllegalArgumentException(
"auto.offset.reset must be 'earliest', 'latest', 'none', or 'by_duration:<ISO-8601>'; got: " + raw);
}
// Usage: normalizeAutoOffsetReset(props.getProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG));
// then pass props to new KafkaConsumer<>(props, ...) Type guard
// Type guard: narrow a free-form config value to a known-good literal union
// (TypeScript-style shown for cross-language clarity; in Java use an enum)
//
// TypeScript:
// type AutoOffsetReset = 'earliest' | 'latest' | 'none' | `by_duration:${string}`;
// function isAutoOffsetReset(v: unknown): v is AutoOffsetReset {
// if (typeof v !== 'string') return false;
// const s = v.trim().toLowerCase();
// if (['earliest','latest','none'].includes(s)) return true;
// if (s.startsWith('by_duration:'))
// return /^P(?!$)(\d+Y)?(\d+M)?(\d+W)?(\d+D)?(T(?=.*\d)(\d+H)?(\d+M)?(\d+(\.\d+)?S)?)?$/.test(s.slice('by_duration:'.length));
// return false;
// }
//
// Java enum equivalent:
// enum AutoOffsetReset { EARLIEST, LATEST, NONE; }
// // validate at the config boundary, store as enum, never as raw String downstream Try / catch
// Construction-time config errors surface as ConfigException wrapped in KafkaException
try {
Consumer<K, V> consumer = new KafkaConsumer<>(props, keyDeser, valDeser);
} catch (KafkaException e) {
Throwable cause = e.getCause();
if (cause instanceof ConfigException) {
// log, alert, fail fast with the offending property name
log.error("Invalid consumer config ({}); fix {} in configuration and restart",
cause.getMessage(), ConsumerConfig.AUTO_OFFSET_RESET_CONFIG);
}
throw e; // construction failure is unrecoverable for this instance
} Prevention
- Source auto.offset.reset from a typed enum or constants, never from an unvalidated string.
- Keep a unit test that asserts every named strategy ('earliest','latest','none') round-trips through AutoOffsetResetStrategy.fromString.
- For 'by_duration', validate the ISO-8601 segment with Duration.parse in a pre-flight check at app startup, not at first poll.
- Treat any ConfigException during KafkaConsumer construction as a deployment-blocking config error; surface it to operators, don't silently default.
When it happens
Trigger: Constructing a KafkaConsumer (or any client that runs ConfigDef validation) with an auto.offset.reset property that is not exactly 'earliest', 'latest', 'none', or 'by_duration:<ISO-8601 duration>'. Also triggered by setting the bare string 'by_duration' with no duration suffix (fromString throws), a negative duration (e.g. by_duration:PT-1H), or a non-ISO duration string (e.g. by_duration:1hour).
Common situations: Typos such as 'earlist' or 'lastest'; using uppercase 'EARLIEST' (only lowercase is accepted); passing 'none ' with trailing whitespace; using the new by_duration feature on a broker/client older than the version that introduced it; mis-copying the ISO-8601 duration format; passing a plain integer or a human duration like '5m' instead of 'PT5M'.
Related errors
- The configured group.id should not be an empty string or whi
- Topic collection to subscribe to cannot contain null or empt
- The configured group.id should not be an empty string or whi
- Topic collection to subscribe to cannot contain null or empt
- Topic pattern to subscribe to cannot be empty
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/861d76cc6e71b543.json.
Report an issue: GitHub.