{"record":{"id":"2a2b9685d77d351c","repo":"apache/cassandra","slug":"required-key-s-is-missing-for-provided-username","errorCode":null,"errorMessage":"Required key '%s' is missing for provided username %s","messagePattern":"Required key '(.+?)' is missing for provided username (.+?)","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/auth/PasswordAuthenticator.java","lineNumber":266,"sourceCode":"\n    public void setup()\n    {\n        String query = String.format(\"SELECT %s FROM %s.%s WHERE role = ?\",\n                                     SALTED_HASH,\n                                     SchemaConstants.AUTH_KEYSPACE_NAME,\n                                     AuthKeyspace.ROLES);\n        authenticateStatement = prepare(query);\n    }\n\n    public AuthenticatedUser legacyAuthenticate(Map<String, String> credentials) throws AuthenticationException\n    {\n        String username = credentials.get(USERNAME_KEY);\n        if (username == null)\n            throw new AuthenticationException(String.format(\"Required key '%s' is missing\", USERNAME_KEY));\n\n        String password = credentials.get(PASSWORD_KEY);\n        if (password == null)\n            throw new AuthenticationException(String.format(\"Required key '%s' is missing for provided username %s\", PASSWORD_KEY, username));\n\n        return authenticate(username, password);\n    }\n\n    public SaslNegotiator newSaslNegotiator(InetAddress clientAddress)\n    {\n        return new PlainTextSaslAuthenticator();\n    }\n\n    @Override\n    public Set<AuthenticationMode> getSupportedAuthenticationModes()\n    {\n        return AUTHENTICATION_MODES;\n    }\n\n    private static SelectStatement prepare(String query)\n    {\n        return (SelectStatement) QueryProcessor.getStatement(query, ClientState.forInternalCalls());","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java#L248-L284","documentation":"Thrown by PasswordAuthenticator.legacyAuthenticate when the credentials map contains a username but is missing the 'password' key. The message includes the username to help identify which login attempt was malformed.","triggerScenarios":"Calling legacyAuthenticate with a map containing 'username' but no 'password' key; client code constructing credentials conditionally and omitting the password when empty.","commonSituations":"Half-populated credentials map from a config parser that skipped an empty password field; custom tooling invoking the legacy authentication API.","solutions":["Include the 'password' key in the credentials map alongside 'username'","Check upstream config parsing for dropped empty-string passwords","Use the SASL negotiator (newSaslNegotiator) path used by CQL native drivers instead of the legacy map API"],"exampleFix":"// before\nMap<String,String> creds = Map.of(\"username\", \"appuser\");\n// after\nMap<String,String> creds = Map.of(\"username\", \"appuser\", \"password\", \"s3cret\");","handlingStrategy":"validation","validationCode":"// validate credentials map before calling\nif (creds.get(\"password\") == null) throw new IllegalArgumentException(\"password required\");\nauthenticator.legacyAuthenticate(creds);","typeGuard":null,"tryCatchPattern":"try { authenticator.legacyAuthenticate(creds); }\ncatch (AuthenticationException e) { /* report missing 'password' key to caller */ }","preventionTips":["Never allow empty/omitted password fields in credential parsing","Prefer the SASL-based native protocol auth path over the legacy map API"],"tags":["authentication","missing-argument","legacy-api"],"backgroundTag":"missing-required-argument","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}