{"record":{"id":"4e20f8641eb0f845","repo":"alibaba/nacos","slug":"plugin-config-value-cannot-be-null-key-4e20f8","errorCode":null,"errorMessage":"Plugin config value cannot be null: {key}","messagePattern":"Plugin config value cannot be null: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"plugin-default-impl/nacos-ldap-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/ldap/LdapAuthPluginConfig.java","lineNumber":132,"sourceCode":"        String password = value(config, PASSWORD, DEFAULT_PASSWORD);\n        String filterPrefix = value(config, FILTER_PREFIX, DEFAULT_FILTER_PREFIX);\n        boolean caseSensitive = parseBoolean(value(config, CASE_SENSITIVE,\n            Boolean.toString(DEFAULT_CASE_SENSITIVE)), CASE_SENSITIVE);\n        boolean ignorePartialResultException = parseBoolean(value(config,\n            IGNORE_PARTIAL_RESULT_EXCEPTION,\n            Boolean.toString(DEFAULT_IGNORE_PARTIAL_RESULT_EXCEPTION)),\n            IGNORE_PARTIAL_RESULT_EXCEPTION);\n        return new LdapAuthPluginConfig(url, baseDn, timeout, userDn, password, filterPrefix,\n            caseSensitive, ignorePartialResultException);\n    }\n    \n    private static String value(Map<String, String> config, String key, String defaultValue) {\n        if (config == null || !config.containsKey(key)) {\n            return defaultValue;\n        }\n        String result = config.get(key);\n        if (result == null) {\n            throw new IllegalArgumentException(\"Plugin config value cannot be null: \" + key);\n        }\n        return result;\n    }\n    \n    private static long parsePositiveLong(String value, String key) {\n        try {\n            long result = Long.parseLong(value);\n            if (result <= 0) {\n                throw new IllegalArgumentException(\"Plugin config value must be positive: \" + key);\n            }\n            return result;\n        } catch (NumberFormatException e) {\n            throw new IllegalArgumentException(\"Plugin config value is not a number: \" + key, e);\n        }\n    }\n    \n    private static boolean parseBoolean(String value, String key) {\n        if (!Boolean.TRUE.toString().equalsIgnoreCase(value)","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/plugin-default-impl/nacos-ldap-auth-plugin/src/main/java/com/alibaba/nacos/plugin/auth/impl/ldap/LdapAuthPluginConfig.java#L114-L150","documentation":"Thrown by LdapAuthPluginConfig.value() when the effective configuration map explicitly contains a key but its value is null. This is distinct from a missing key (which returns the default). The presence of key->null in the map signals a malformed configuration source, so the parser rejects it with IllegalArgumentException naming the offending key.","triggerScenarios":"LdapAuthPluginConfig.from(config) is called with a Map where one of the known keys (url, base-dn, timeout, user-dn, password, filter-prefix, case-sensitive, ignore-partial-result-exception) is present but maps to a null value.","commonSituations":"A YAML/properties file declares a key with no value (e.g. \"nacos.plugin.auth.ldap.url=\"); a config-loading layer puts the key in the map with a null placeholder; an environment variable override resolves to null.","solutions":["Inspect the error message to identify which key has the null value, then provide an explicit value in the config source.","If the key should be optional, remove it from the config map entirely so the default kicks in (the from() method only throws when the key is present-but-null).","Sanitize the config map before passing it to from(): strip entries whose value is null."],"exampleFix":"// before: map contains a key with null value\nMap<String,String> config = new HashMap<>();\nconfig.put(\"url\", null); // present but null -> throws\nLdapAuthPluginConfig.from(config);\n\n// after: omit the key so the default applies, or set a real value\nMap<String,String> config = new HashMap<>();\n// url omitted -> defaults to ldap://localhost:389\nLdapAuthPluginConfig.from(config);","handlingStrategy":"validation","validationCode":"// Strip null-valued entries before parsing\nMap<String, String> sanitized = new LinkedHashMap<>();\nfor (Map.Entry<String, String> entry : config.entrySet()) {\n    if (entry.getValue() != null) {\n        sanitized.put(entry.getKey(), entry.getValue());\n    }\n}\nLdapAuthPluginConfig.from(sanitized);","typeGuard":"static boolean hasNoNullValues(Map<String, String> config) {\n    return config == null || config.values().stream().noneMatch(Objects::isNull);\n}","tryCatchPattern":"try {\n    LdapAuthPluginConfig parsed = LdapAuthPluginConfig.from(config);\n} catch (IllegalArgumentException e) {\n    // message names the offending key; fix the config source\n}","preventionTips":["Never put a key with an empty value in the LDAP config map; omit it to use the default.","Sanitize config maps from external sources before passing to from().","Add a config-validation step in the deployment pipeline."],"tags":["auth","ldap","config","validation","illegal-argument","java"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}