apache/pulsar · error · IllegalArgumentException

Only one of serdeClassName or schemaType should be set

Error message

Only one of serdeClassName or schemaType should be set

What it means

Schema configuration conflict in SourceConfigUtils.validateAndExtractDetails: after resolving the source class's type, both serdeClassName and schemaType were set on the SourceConfig, but exactly one serialization mechanism is allowed; the redundant field on the source config is the faulty input.

Source

Thrown at pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/SourceConfigUtils.java:344

                  String.format("Source class %s implements %s but batch source source config is not specified",
                    sourceClass.getName(), BatchSource.class.getName()));
            }
        }

        // extract type from source class
        TypeDefinition typeArg;

        try {
            typeArg = getSourceType(sourceClass);
        } catch (Exception e) {
            throw new IllegalArgumentException(
                    String.format("Failed to resolve type for Source class %s", sourceClassName), e);
        }

        // Only one of serdeClassName or schemaType should be set
        if (!StringUtils.isEmpty(sourceConfig.getSerdeClassName()) && !StringUtils
                .isEmpty(sourceConfig.getSchemaType())) {
            throw new IllegalArgumentException("Only one of serdeClassName or schemaType should be set");
        }

        if (!StringUtils.isEmpty(sourceConfig.getSerdeClassName())) {
            ValidatorUtils.validateSerde(sourceConfig.getSerdeClassName(), typeArg, sourceFunction.getTypePool(),
                    false);
        }
        if (!StringUtils.isEmpty(sourceConfig.getSchemaType())) {
            ValidatorUtils.validateSchema(sourceConfig.getSchemaType(), typeArg, sourceFunction.getTypePool(),
                    false);
        }

        if (sourceConfig.getProducerConfig() != null && sourceConfig.getProducerConfig().getCryptoConfig() != null) {
            ValidatorUtils
                    .validateCryptoKeyReader(sourceConfig.getProducerConfig().getCryptoConfig(),
                            sourceFunction.getTypePool(), true);
        }

        // validate user defined config if enabled and classloading is enabled

View on GitHub (pinned to 820761864e)

Solutions

  1. Set either serdeClassName or schemaType, not both

Example fix

// before
{"serdeClassName":"com.example.MySerde","schemaType":"org.apache.pulsar.common.schema.SchemaType.STRING"}
// after
{"schemaType":"org.apache.pulsar.common.schema.SchemaType.STRING"}
Defensive patterns

Strategy: validation

Validate before calling

if (config.getSerdeClassName() != null && !config.getSerdeClassName().isEmpty()
    && config.getSchemaType() != null && !config.getSchemaType().isEmpty()) {
    throw new IllegalArgumentException("Set only one of serdeClassName or schemaType");
}

Try / catch

try { validateAndExtractDetails(...); } catch (IllegalArgumentException e) { if (e.getMessage().contains("serdeClassName or schemaType")) { config.setSerdeClassName(null); /* keep schemaType */ } else { throw e; } }

Prevention

When it happens

Trigger: validateAndExtractDetails finds both sourceConfig.getSerdeClassName() and sourceConfig.getSchemaType() non-empty.

Common situations: Merging config templates where one sets schemaType and another serdeClassName; upgrading an old source config by adding schemaType without removing serdeClassName; UI/CLI flags both --serde-classname and --schema-type supplied.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/96d80674d5fe13de. Report an issue: GitHub.