{"record":{"id":"09221b77b9a26b57","repo":"apache/pulsar","slug":"exception-caused-while-converting-configuration","errorCode":null,"errorMessage":"Exception caused while converting configuration: ${message}","messagePattern":"Exception caused while converting configuration: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-broker-common/src/main/java/org/apache/pulsar/common/configuration/PulsarConfigurationLoader.java","lineNumber":255,"sourceCode":"            throws RuntimeException {\n        try {\n            final ServiceConfiguration convertedConf = ServiceConfiguration.class\n                    .getDeclaredConstructor().newInstance();\n            Field[] confFields = conf.getClass().getDeclaredFields();\n            Properties sourceProperties = conf.getProperties();\n            Properties targetProperties = convertedConf.getProperties();\n            Arrays.stream(confFields).forEach(confField -> {\n                try {\n                    confField.setAccessible(true);\n                    Field convertedConfField = ServiceConfiguration.class.getDeclaredField(confField.getName());\n                    if (!Modifier.isStatic(convertedConfField.getModifiers())\n                            && convertedConfField.getDeclaredAnnotation(FieldContext.class) != null) {\n                        convertedConfField.setAccessible(true);\n                        convertedConfField.set(convertedConf, confField.get(conf));\n                    }\n                } catch (NoSuchFieldException e) {\n                    if (!ignoreNonExistMember) {\n                        throw new IllegalArgumentException(\n                                \"Exception caused while converting configuration: \" + e.getMessage());\n                    }\n                    // add unknown fields to properties\n                    try {\n                        String propertyName = confField.getName();\n                        if (!sourceProperties.containsKey(propertyName) && confField.get(conf) != null) {\n                            targetProperties.put(propertyName, confField.get(conf));\n                        }\n                    } catch (Exception ignoreException) {\n                        // should not happen\n                    }\n                } catch (IllegalAccessException e) {\n                    throw new RuntimeException(\"Exception caused while converting configuration: \" + e.getMessage());\n                }\n            });\n            // Put the rest of properties to new config\n            targetProperties.putAll(sourceProperties);\n            return convertedConf;","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-broker-common/src/main/java/org/apache/pulsar/common/configuration/PulsarConfigurationLoader.java#L237-L273","documentation":"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).","triggerScenarios":"Calling PulsarConfigurationLoader.convertFrom(conf, false) where the source configuration class has fields that do not exist on the target configuration class.","commonSituations":"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.","solutions":["Call convertFrom(conf, true) to ignore fields that don't exist on the target (they are collected into target properties instead)","Add the missing field to the target configuration class if it should carry that setting","Remove or default the extra field in the source configuration","Align the source and target configuration class versions"],"exampleFix":"// before\nServiceConfiguration svc = PulsarConfigurationLoader.convertFrom(conf, false);\n// after (tolerate fields missing on the target)\nServiceConfiguration svc = PulsarConfigurationLoader.convertFrom(conf, true);","handlingStrategy":"validation","validationCode":"// Pre-check that all source fields exist on the target\nboolean compatible = java.util.Arrays.stream(sourceClass.getDeclaredFields())\n    .allMatch(sf -> {\n        try { targetClass.getDeclaredField(sf.getName()); return true; }\n        catch (NoSuchFieldException e) { return false; }\n    });\nif (!compatible && strictMode) {\n    throw new IllegalStateException(\"Source has fields missing on target; use ignoreNonExistMember=true\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    ServiceConfiguration svc = PulsarConfigurationLoader.convertFrom(conf, false);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"Exception caused while converting configuration\")) {\n        log.error(\"Missing target field: {}\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Prefer convertFrom(conf, true) unless you need strict field parity","Keep source and target configuration classes field-aligned across versions","Test conversions between config types in unit tests"],"tags":["reflection","configuration","conversion"],"backgroundTag":"config-field-mismatch","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}