provectus/kafka-ui · error · ValidationException

Serde ' ' can't be applied to ' ' topic

Error message

Serde '%s' can't be applied to '%s' topic %s

What it means

getSerdeForDeserialize validates the explicitly requested serdeName against the topic and type (key or value) via canDeserialize. If the serde exists but cannot deserialize that side of that topic, this ValidationException is thrown; when no name is given, kafka-ui auto-suggests a suitable serde instead.

Solutions

  1. Omit the keySerde/valueSerde parameter so kafka-ui auto-suggests a suitable serde for the topic
  2. Pick a serde that supports that topic side, e.g. String for non-registry-encoded keys
  3. If using SR-based serdes, confirm the subject/mapping for this topic (and key vs value) exists in Schema Registry
  4. Re-check the request: ensure a value-side serde wasn't passed as keySerde or vice versa

Example fix

// before
GET /api/clusters/c1/topics/t/messages?valueSerde=Avro // Avro can't deserialize this topic's values
// after
GET /api/clusters/c1/topics/t/messages // let kafka-ui suggest the serde
// or pick a compatible serde explicitly
GET /api/clusters/c1/topics/t/messages?valueSerde=String
Defensive patterns

Strategy: validation

Validate before calling

var serdes = deserializationService.getSerdesFor(cluster);
boolean usable = serdes.serdeForName(serdeName)
    .map(s -> s.canDeserialize(topic, type))
    .orElse(false);
if (!usable) serdeName = null; // let kafka-ui suggest one

Try / catch

try {
  messages = kafkaUiApi.getMessages(topic, keySerde, valueSerde);
} catch (ValidationException e) {
  if (e.getMessage().contains("can't be applied")) {
    messages = kafkaUiApi.getMessages(topic, null, null); // auto-suggest serdes
  }
}

Prevention

When it happens

Trigger: Requesting message consumption/preview with an explicit keySerde or valueSerde query parameter whose canDeserialize(topic, type) is false - e.g. asking an Avro Schema Registry serde to deserialize the key of a topic whose key subject/mapping doesn't exist, or using a serde that only supports VALUE.

Common situations: Saved UI links/queries carrying a serde name from a different topic; topic renamed or schema subject mappings changed after the query was bookmarked; swapping keySerde and valueSerde parameters in an API call; cluster migration where the new cluster lacks the subject for that topic.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of provectus/kafka-ui@83b5a60cc0 (2026-09-08). Data as JSON: /api/errors/c775418ad61cc5a3. Report an issue: GitHub.

Appendix: source

Thrown at kafka-ui-api/src/main/java/com/provectus/kafka/ui/service/DeserializationService.java:72

        .orElseThrow(() -> new ValidationException(
            String.format("Serde %s not found", serdeName)));
    if (!serde.canSerialize(topic, type)) {
      throw new ValidationException(
          String.format("Serde %s can't be applied for '%s' topic's %s serialization", serde, topic, type));
    }
    return serde.serializer(topic, type);
  }

  private SerdeInstance getSerdeForDeserialize(KafkaCluster cluster,
                                               String topic,
                                               Serde.Target type,
                                               @Nullable String serdeName) {
    var serdes = getSerdesFor(cluster);
    if (serdeName != null) {
      var serde = serdes.serdeForName(serdeName)
          .orElseThrow(() -> new ValidationException(String.format("Serde '%s' not found", serdeName)));
      if (!serde.canDeserialize(topic, type)) {
        throw new ValidationException(
            String.format("Serde '%s' can't be applied to '%s' topic %s", serdeName, topic, type));
      }
      return serde;
    } else {
      return serdes.suggestSerdeForDeserialize(topic, type);
    }
  }

  public ProducerRecordCreator producerRecordCreator(KafkaCluster cluster,
                                                     String topic,
                                                     String keySerdeName,
                                                     String valueSerdeName) {
    return new ProducerRecordCreator(
        getSerializer(cluster, topic, Serde.Target.KEY, keySerdeName),
        getSerializer(cluster, topic, Serde.Target.VALUE, valueSerdeName)
    );
  }

View on GitHub (pinned to 83b5a60cc0)