apache/pulsar · error · IllegalArgumentException

Exception caused while converting configuration: ${message}

Error message

Exception caused while converting configuration: ${message}

What it means

convertFrom copies fields from a source PulsarConfiguration object to a target configuration type reflectively. When a source field has no matching field in the target class and ignoreNonExistMember is false, it throws this IllegalArgumentException carrying e.getMessage() (the NoSuchFieldException text naming the missing field).

Source

Thrown at pulsar-broker-common/src/main/java/org/apache/pulsar/common/configuration/PulsarConfigurationLoader.java:255

            throws RuntimeException {
        try {
            final ServiceConfiguration convertedConf = ServiceConfiguration.class
                    .getDeclaredConstructor().newInstance();
            Field[] confFields = conf.getClass().getDeclaredFields();
            Properties sourceProperties = conf.getProperties();
            Properties targetProperties = convertedConf.getProperties();
            Arrays.stream(confFields).forEach(confField -> {
                try {
                    confField.setAccessible(true);
                    Field convertedConfField = ServiceConfiguration.class.getDeclaredField(confField.getName());
                    if (!Modifier.isStatic(convertedConfField.getModifiers())
                            && convertedConfField.getDeclaredAnnotation(FieldContext.class) != null) {
                        convertedConfField.setAccessible(true);
                        convertedConfField.set(convertedConf, confField.get(conf));
                    }
                } catch (NoSuchFieldException e) {
                    if (!ignoreNonExistMember) {
                        throw new IllegalArgumentException(
                                "Exception caused while converting configuration: " + e.getMessage());
                    }
                    // add unknown fields to properties
                    try {
                        String propertyName = confField.getName();
                        if (!sourceProperties.containsKey(propertyName) && confField.get(conf) != null) {
                            targetProperties.put(propertyName, confField.get(conf));
                        }
                    } catch (Exception ignoreException) {
                        // should not happen
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Exception caused while converting configuration: " + e.getMessage());
                }
            });
            // Put the rest of properties to new config
            targetProperties.putAll(sourceProperties);
            return convertedConf;

View on GitHub (pinned to 820761864e)

Solutions

  1. Call convertFrom(conf, true) to ignore fields that don't exist on the target (they are collected into target properties instead)
  2. Add the missing field to the target configuration class if it should carry that setting
  3. Remove or default the extra field in the source configuration
  4. Align the source and target configuration class versions

Example fix

// before
ServiceConfiguration svc = PulsarConfigurationLoader.convertFrom(conf, false);
// after (tolerate fields missing on the target)
ServiceConfiguration svc = PulsarConfigurationLoader.convertFrom(conf, true);
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check that all source fields exist on the target
boolean compatible = java.util.Arrays.stream(sourceClass.getDeclaredFields())
    .allMatch(sf -> {
        try { targetClass.getDeclaredField(sf.getName()); return true; }
        catch (NoSuchFieldException e) { return false; }
    });
if (!compatible && strictMode) {
    throw new IllegalStateException("Source has fields missing on target; use ignoreNonExistMember=true");
}

Try / catch

try {
    ServiceConfiguration svc = PulsarConfigurationLoader.convertFrom(conf, false);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Exception caused while converting configuration")) {
        log.error("Missing target field: {}", e.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling PulsarConfigurationLoader.convertFrom(conf, false) where the source configuration class has fields that do not exist on the target configuration class.

Common situations: Converting a newer/extended config object to an older or narrower config type that lacks some fields; intentionally strict conversion where the user forgot that extra fields exist; version skew between modules defining different config classes.

Related errors


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