provectus/kafka-ui · error · ValidationException

Serde can't be applied for ' ' topic's serialization

Error message

Serde %s can't be applied for '%s' topic's %s serialization

What it means

DeserializationService.getSerializer looks up the requested serde by name and then checks serde.canSerialize(topic, type) before returning a serializer. This error means the serde exists but explicitly does not support serializing the requested type (key or value) for that topic, so producing with it is refused.

Solutions

  1. Use a serde that supports the topic and type: pick String or Json for generic values, or configure the SR/Protobuf serde's topic mapping so canSerialize passes
  2. Check that the correct type (key vs value) is selected for the serde in the produce request
  3. Verify the serde's template-based configuration actually covers this topic name

Example fix

// before
{"serdeName":"SchemaRegistry","topic":"events","type":"VALUE","value":"..."} // serde not applicable to this topic
// after
{"serdeName":"String","topic":"events","type":"VALUE","value":"..."} // or configure SR mapping for 'events'
Defensive patterns

Strategy: try-catch

Validate before calling

var serdes = deserializationService.getSerdesFor(cluster);
boolean ok = serdes.serdeForName(serdeName)
    .map(s -> s.canSerialize(topic, type))
    .orElse(false);
if (!ok) { /* pick another serde or configure the mapping */ }

Try / catch

try {
  kafkaUiApi.produce(topic, serdeName, type, value);
} catch (ValidationException e) {
  if (e.getMessage().contains("can't be applied")) {
    // fall back to String serde or reconfigure the serde mapping
  }
}

Prevention

When it happens

Trigger: POSTing to the kafka-ui messages produce endpoint with a serdeName whose canSerialize(topic, type) returns false - e.g. a Schema Registry serde for a topic with no compatible subject mapping, or a proto/avro serde where the topic/message-type selection doesn't match.

Common situations: Selecting the wrong serde in the UI produce form; key vs value mismatch in the type parameter; builtin serde that requires a configured topic-to-schema mapping, but the mapping doesn't cover this topic name; reusing a serde name copied from another cluster/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/74ae93e429abef23. Report an issue: GitHub.

Appendix: source

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

      var cluster = clustersStorage.getClusterByName(clusterProperties.getName()).get();
      clusterSerdes.put(cluster.getName(), serdesInitializer.init(env, clustersProperties, i));
    }
  }

  private ClusterSerdes getSerdesFor(KafkaCluster cluster) {
    return clusterSerdes.get(cluster.getName());
  }

  private Serde.Serializer getSerializer(KafkaCluster cluster,
                                         String topic,
                                         Serde.Target type,
                                         String serdeName) {
    var serdes = getSerdesFor(cluster);
    var serde = serdes.serdeForName(serdeName)
        .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;

View on GitHub (pinned to 83b5a60cc0)