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

  1. Provide seekTo entries (format `partition::offset` for OFFSET, `partition::timestampMillis` for TIMESTAMP)
  2. Use seekType=BEGINNING or LATEST if you don't need specific positions
  3. 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

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


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));
  }

  @Override

View on GitHub (pinned to 83b5a60cc0)