{"record":{"id":"f6080c35c6a6496d","repo":"spring-projects/spring-security","slug":"expression-was-null-but-expected-boolean-result","errorCode":null,"errorMessage":"Expression was null but expected boolean result '{expressionString}'","messagePattern":"Expression was null but expected boolean result '(.+?)'","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/springframework/security/access/expression/ExpressionUtils.java","lineNumber":32,"sourceCode":" * limitations under the License.\n */\n\npackage org.springframework.security.access.expression;\n\nimport org.springframework.expression.EvaluationContext;\nimport org.springframework.expression.EvaluationException;\nimport org.springframework.expression.Expression;\n\npublic final class ExpressionUtils {\n\n\tprivate ExpressionUtils() {\n\t}\n\n\tpublic static boolean evaluateAsBoolean(Expression expr, EvaluationContext ctx) {\n\t\ttry {\n\t\t\tBoolean result = expr.getValue(ctx, Boolean.class);\n\t\t\tif (result == null) {\n\t\t\t\tthrow new IllegalArgumentException(\n\t\t\t\t\t\t\"Expression was null but expected boolean result '\" + expr.getExpressionString() + \"'\");\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t\tcatch (EvaluationException ex) {\n\t\t\tthrow new IllegalArgumentException(\"Failed to evaluate expression '\" + expr.getExpressionString() + \"'\",\n\t\t\t\t\tex);\n\t\t}\n\t}\n\n}\n","sourceCodeStart":14,"sourceCodeEnd":44,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/core/src/main/java/org/springframework/security/access/expression/ExpressionUtils.java#L14-L44","documentation":"Spring Security's ExpressionUtils.evaluateAsBoolean evaluates a SpEL security expression (e.g. from @PreAuthorize) expecting a Boolean result. If the expression evaluates to null instead of true/false, the library throws IllegalArgumentException because authorization requires a definitive boolean answer. This typically happens when the expression returns a null value (e.g. calling a method or accessing a property that yields null).","triggerScenarios":"Calling ExpressionUtils.evaluateAsBoolean(expr, ctx) where expr.getValue(ctx, Boolean.class) returns null — e.g. a @PreAuthorize expression like \"@bean.method()\" whose return value is null, or a property access resolving to null.","commonSituations":"Custom authorization expressions invoking service/bean methods that return null instead of boolean; security expressions referencing missing properties on the root object; refactoring a check from 'hasRole(...)' to a custom check that returns null on some paths.","solutions":["Change the security expression so it always returns a boolean, e.g. wrap null-able calls: @bean.findUser() != null and @bean.findUser().active","Use null-safe SpEL operators (?.) in the expression so comparisons yield true/false instead of null","If you own the called method, return Boolean.FALSE instead of null when the check fails","Catch IllegalArgumentException around the authorization call and treat it as a denial with a clearer message"],"exampleFix":"// before\n@PreAuthorize(\"@permService.checkAccess(#doc)\")\n// after\n@PreAuthorize(\"@permService.checkAccess(#doc) == true\")  // or make checkAccess return boolean, never null","handlingStrategy":"validation","validationCode":"Boolean val = expr.getValue(ctx, Boolean.class);\nif (val == null) throw new IllegalStateException(\"Expression '\" + expr.getExpressionString() + \"' must not return null\");","typeGuard":"if (expr.getValue(ctx) instanceof Boolean b) { /* safe to authorize */ }","tryCatchPattern":"try { ExpressionUtils.evaluateAsBoolean(expr, ctx); }\ncatch (IllegalArgumentException e) { denyAccess(); }","preventionTips":["Make every security-expression target method return primitive boolean","Use == true comparison in @PreAuthorize to coerce null checks","Use SpEL ?. and ?: operators for null-able paths","Unit-test security expressions against null-returning services"],"tags":["spel","security","authorization","null-value"],"backgroundTag":"null-argument","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}