provectus/kafka-ui · error · ValidationException
seekTo should be set if seekType is
Error message
seekTo should be set if seekType is ${seekType} What it means
MessagesController.parseSeekTo resolves the seek position for the GET messages API. If seekType is OFFSET, TIMESTAMP (or otherwise neither LATEST nor BEGINNING), an explicit seekTo list is mandatory; when it is null or empty a ValidationException is thrown.
Solutions
- Provide seekTo entries (format `partition::offset` for OFFSET, `partition::timestampMillis` for TIMESTAMP)
- Use seekType=BEGINNING or LATEST if you don't need specific positions
- Fix the client to always send seekTo when a non-default seekType is used
Example fix
// before GET /api/clusters/local/topics/my-topic/messages?seekType=OFFSET // after GET /api/clusters/local/topics/my-topic/messages?seekType=OFFSET&seekTo=0::42&seekTo=1::17
Defensive patterns
Strategy: validation
Validate before calling
function buildMessagesQuery(seekType, seekTo) {
if (seekType !== 'LATEST' && seekType !== 'BEGINNING' && (!seekTo || seekTo.length === 0)) {
throw new Error('seekTo is required for seekType ' + seekType);
}
return { seekType, seekTo };
} Try / catch
try {
const res = await api.getMessages(params);
} catch (e) {
if (e.status === 400 && /seekTo should be set/.test(e.message)) {
params.seekTo = computeSeekTo(params.seekType);
retry();
}
} Prevention
- Default to seekType=BEGINNING or LATEST when no explicit positions are needed
- Compute seekTo from partition metadata before calling the API
- Add client-side request validation mirroring the server contract
When it happens
Trigger: Calling GET /api/clusters/{c}/topics/{t}/messages with seekType=OFFSET or TIMESTAMP but omitting seekTo, or sending an empty seekTo list.
Common situations: API clients using the generated SDK defaults that leave seekTo unset; frontend filters requesting offsets without computing the offset list; Swagger 'try it out' leaving seekTo blank.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Wrong seekTo argument format. See API docs for details
- Schema Registry is not set for cluster
- ' ' is not valid json
- ' ' does not fit schema
- Something went wrong during adding replicas
AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08).
Data as JSON: /api/errors/f85bd7f9b2ad76e5.
Report an issue: GitHub.
Appendix: source
Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/MessagesController.java:160
return validateAccess(context).then(
createTopicMessage.flatMap(msg ->
messagesService.sendMessage(getCluster(clusterName), topicName, msg).then()
).map(ResponseEntity::ok)
).doOnEach(sig -> audit(context, sig));
}
/**
* The format is [partition]::[offset] for specifying offsets
* or [partition]::[timestamp in millis] for specifying timestamps.
*/
@Nullable
private Map<TopicPartition, Long> parseSeekTo(String topic, SeekTypeDTO seekType, List<String> seekTo) {
if (seekTo == null || seekTo.isEmpty()) {
if (seekType == SeekTypeDTO.LATEST || seekType == SeekTypeDTO.BEGINNING) {
return null;
}
throw new ValidationException("seekTo should be set if seekType is " + seekType);
}
return seekTo.stream()
.map(p -> {
String[] split = p.split("::");
if (split.length != 2) {
throw new IllegalArgumentException(
"Wrong seekTo argument format. See API docs for details");
}
return Pair.of(
new TopicPartition(topic, Integer.parseInt(split[0])),
Long.parseLong(split[1])
);
})
.collect(toMap(Pair::getKey, Pair::getValue));
}
@OverrideView on GitHub (pinned to 83b5a60cc0)