{"record":{"id":"e42911e0d056da59","repo":"quarkusio/quarkus","slug":"missing-password-provider-for-password-type-pas","errorCode":null,"errorMessage":"Missing password provider for password type: ${passwordType}","messagePattern":"Missing password provider for password type: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java","lineNumber":64,"sourceCode":"            PanacheEntityPredicateBuildItem panacheEntityPredicate, FieldDesc passwordProviderField,\n            Expr thisRef, Expr requestParam, Expr userVar, BlockCreator bc) {\n        // if(user == null) throw new AuthenticationFailedException();\n\n        PasswordType passwordType = passwordTypeValue != null ? PasswordType.valueOf(passwordTypeValue.asEnum())\n                : PasswordType.MCF;\n\n        bc.if_(bc.isNull(userVar), trueBranch -> {\n            Expr exceptionInstance = trueBranch\n                    .new_(ConstructorDesc.of(AuthenticationFailedException.class));\n            trueBranch.invokeStatic(passwordActionMethod(), Const.of(passwordType));\n            trueBranch.throw_(exceptionInstance);\n        });\n\n        // :pass = user.pass | user.getPass()\n        LocalVar pass = bc.localVar(\"pass\", jpaSecurityDefinition.password.readValue(bc, userVar));\n\n        if (passwordType == PasswordType.CUSTOM && passwordProviderValue == null) {\n            throw new RuntimeException(\"Missing password provider for password type: \" + passwordType);\n        }\n\n        Expr storedPassword;\n        switch (passwordType) {\n            case CUSTOM:\n                String passwordProviderClassStr = passwordProviderValue.asString();\n                String passwordProviderMethod = \"getPassword\";\n                LocalVar passwordProviderInstanceField = bc.localVar(\"ppField\",\n                        bc.get(thisRef.field(passwordProviderField)));\n                bc.if_(bc.isNull(passwordProviderInstanceField), trueBranch -> {\n                    Expr passwordProviderInstance = trueBranch\n                            .new_(ConstructorDesc.of(ClassDesc.of(passwordProviderClassStr)));\n                    trueBranch.set(thisRef.field(passwordProviderField), passwordProviderInstance);\n                });\n                LocalVar objectToInvokeOn = bc.localVar(\"ppObj\",\n                        bc.get(thisRef.field(passwordProviderField)));\n\n                // :getPasswordMethod(:pass);","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security-jpa-common/deployment/src/main/java/io/quarkus/security/jpa/common/deployment/JpaSecurityIdentityUtil.java#L46-L82","documentation":"JpaSecurityIdentityUtil.buildIdentity() generates bytecode for the JPA identity provider. When the entity's password field is declared as PasswordType.CUSTOM, a PasswordProvider must be supplied via configuration; if passwordProviderValue is null, it throws RuntimeException because it cannot generate password-verification code without the provider class.","triggerScenarios":"Annotating the password field/setter with @Password(PasswordType.CUSTOM) without registering a PasswordProvider implementation/pointing to one in configuration.","commonSituations":"Choosing CUSTOM for a legacy hash algorithm but forgetting to specify the provider class; renaming/removing the PasswordProvider class so the config value no longer resolves; copy-pasting an entity definition with CUSTOM type from an example that included a provider.","solutions":["Configure the password provider class for the entity, e.g. via the @Password attribute value or the corresponding quarkus.security-jpa config property.","Use a built-in PasswordType (BCRYPT, etc.) instead of CUSTOM if a provider is not available.","Implement a PasswordProvider for your hash algorithm and reference it."],"exampleFix":"// before\n@Password(PasswordType.CUSTOM)\nprivate String password;\n\n// after\n@Password(value = PasswordType.CUSTOM, provider = com.app.LegacyPasswordProvider.class)\nprivate String password;","handlingStrategy":"validation","validationCode":"if (passwordType == PasswordType.CUSTOM && passwordProviderClass == null) {\n    throw new IllegalStateException(\"CUSTOM requires a PasswordProvider\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set the provider class when using @Password(PasswordType.CUSTOM)","Prefer built-in PasswordTypes when possible","Keep provider class references in sync after renames"],"tags":["security","jpa","password","build-time","bytecode-generation"],"backgroundTag":"missing-password-provider","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}