{"record":{"id":"e3736386d26dabd7","repo":"elastic/elasticsearch","slug":"unknown-keys-in-user-definition-for","errorCode":null,"errorMessage":"Unknown keys in user definition {} for {}","messagePattern":"Unknown keys in user definition (.+?) for (.+?)","errorType":"validation","errorClass":"TestClustersException","httpStatus":null,"severity":"error","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java","lineNumber":743,"sourceCode":"        if (destination.contains(\"..\")) {\n            throw new IllegalArgumentException(\"extra config file destination can't be relative, was \" + destination + \" for \" + this);\n        }\n        extraConfigFiles.put(destination, from, normalization);\n    }\n\n    @Override\n    public void extraJarFiles(FileCollection from) {\n        extraJarConfigurations.add(from);\n    }\n\n    @Override\n    public void user(Map<String, String> userSpec) {\n        Set<String> keys = new HashSet<>(userSpec.keySet());\n        keys.remove(\"username\");\n        keys.remove(\"password\");\n        keys.remove(\"role\");\n        if (keys.isEmpty() == false) {\n            throw new TestClustersException(\"Unknown keys in user definition \" + keys + \" for \" + this);\n        }\n        Map<String, String> cred = new LinkedHashMap<>();\n        cred.put(\"useradd\", userSpec.getOrDefault(\"username\", \"test_user\"));\n        cred.put(\"-p\", userSpec.getOrDefault(\"password\", \"x-pack-test-password\"));\n        cred.put(\"-r\", userSpec.getOrDefault(\"role\", \"_es_test_root\"));\n        credentials.add(cred);\n    }\n\n    private File getBuildPluginFile(String name) {\n        URL resource = getClass().getResource(name);\n        return fileOperations.getResources().getText().fromUri(resource).asFile();\n    }\n\n    @Override\n    public void rolesFile(File rolesYml) {\n        roleFiles.add(rolesYml);\n    }\n","sourceCodeStart":725,"sourceCodeEnd":761,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java#L725-L761","documentation":"Thrown by user(userSpec) when the supplied map contains keys other than 'username', 'password', and 'role'. The node builds an elasticsearch-users useradd invocation from exactly those three keys; any extra key would be ignored silently, so the API rejects it to catch typos and schema drift.","triggerScenarios":"Calling node.user([username:'u', password:'p', role:'r', extra:'x']) with a stray key. Common culprits: 'roles' (plural) instead of 'role', 'pass' instead of 'password', 'name' instead of 'username', or test framework boilerplate passing through extra fields.","commonSituations":"Migrating from an older API that accepted 'roles' plural. Copy-paste from a REST example that uses different field names. Test fixture that forwards an unfiltered map.","solutions":["Restrict the map to exactly username/password/role.","Replace 'roles' with 'role', 'pass' with 'password', 'name'/'user' with 'username'.","If you need multiple roles, pass them comma-separated as the single 'role' value (matches elasticsearch-users -r semantics).","Filter the map before calling: userSpec.subMap(['username','password','role'])."],"exampleFix":"// before: wrong key names\nuser([user: 'alice', pass: 'secret', roles: 'superuser'])\n// after: correct keys\nuser([username: 'alice', password: 'secret', role: 'superuser'])","handlingStrategy":"validation","validationCode":"static final Set<String> USER_KEYS = Set.of(\"username\", \"password\", \"role\");\nstatic Map<String,String> sanitizeUser(Map<String,String> in) {\n    Set<String> extra = new HashSet<>(in.keySet());\n    extra.removeAll(USER_KEYS);\n    if (!extra.isEmpty()) {\n        throw new IllegalArgumentException(\"Unknown user keys \" + extra + \"; allowed \" + USER_KEYS);\n    }\n    return in;\n}\n// Use: node.user(sanitizeUser(spec));","typeGuard":"static boolean isValidUserSpec(Map<String,String> in) {\n    return USER_KEYS.containsAll(in.keySet());\n}","tryCatchPattern":null,"preventionTips":["Use exactly username/password/role keys.","Map 'roles'->'role', 'pass'->'password', 'name'->'username' when migrating.","Pass multiple roles as a comma-separated 'role' value."],"tags":["testclusters","security","users","validation","config"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}