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

  1. Set auto.offset.reset to one of the exact literals 'earliest', 'latest', or 'none' (lowercase, no whitespace).
  2. If you want a by-duration reset, use the exact format 'by_duration:PnDTnHnMn.nS' (e.g. 'by_duration:PT5M', 'by_duration:P1DT2H').
  3. Trim any trailing/leading whitespace and confirm casing in your config source (properties file, env var, command line).
  4. 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

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


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