{"record":{"id":"bd2db295dd99f598","repo":"apache/druid","slug":"s-set-to-false-but-has-been-removed-see-s-fo","errorCode":null,"errorMessage":"%s set to 'false', but has been removed, see %s for details for how to migrate to SQL compliant behavior","messagePattern":"(.+?) set to 'false', but has been removed, see (.+?) for details for how to migrate to SQL compliant behavior","errorType":"validation","errorClass":"ISE","httpStatus":null,"severity":"critical","filePath":"processing/src/main/java/org/apache/druid/guice/StartupInjectorBuilder.java","lineNumber":154,"sourceCode":"    {\n      final boolean defaultValueMode = Boolean.parseBoolean(\n          properties.getProperty(NULL_HANDLING_CONFIG_STRING, \"false\")\n      );\n      if (defaultValueMode) {\n        final String docsLink = StringUtils.format(\"https://druid.apache.org/docs/%s/release-info/migr-ansi-sql-null\", getVersionString());\n        throw new ISE(\n            \"%s set to 'true', but has been removed, see %s for details for how to migrate to SQL compliant behavior\",\n            NULL_HANDLING_CONFIG_STRING,\n            docsLink\n        );\n      }\n\n      final boolean no3vl = !Boolean.parseBoolean(\n          properties.getProperty(THREE_VALUE_LOGIC_CONFIG_STRING, \"true\")\n      );\n      if (no3vl) {\n        final String docsLink = StringUtils.format(\"https://druid.apache.org/docs/%s/release-info/migr-ansi-sql-null\", getVersionString());\n        throw new ISE(\n            \"%s set to 'false', but has been removed, see %s for details for how to migrate to SQL compliant behavior\",\n            THREE_VALUE_LOGIC_CONFIG_STRING,\n            docsLink\n        );\n      }\n\n      final boolean nonStrictExpressions = !Boolean.parseBoolean(\n          properties.getProperty(ExpressionProcessingConfig.NULL_HANDLING_LEGACY_LOGICAL_OPS_STRING, \"true\")\n      );\n      if (nonStrictExpressions) {\n        final String docsLink = StringUtils.format(\"https://druid.apache.org/docs/%s/release-info/migr-ansi-sql-null\", getVersionString());\n        throw new ISE(\n            \"%s set to 'false', but has been removed, see %s for details for how to migrate to SQL compliant behavior\",\n            ExpressionProcessingConfig.NULL_HANDLING_LEGACY_LOGICAL_OPS_STRING,\n            docsLink\n        );\n      }\n","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/guice/StartupInjectorBuilder.java#L136-L172","documentation":"The three-value-logic toggle druid.sql.expressionProcessor/three-value-logic config has been removed; Druid now always uses three-valued logic when SQL-compliant null handling is on. StartupInjectorBuilder.validate() throws this ISE at startup if the property is set to 'false' to prevent silently reverting to legacy non-3VL semantics.","triggerScenarios":"validate() computes no3vl = !Boolean.parseBoolean(properties.getProperty(THREE_VALUE_LOGIC_CONFIG_STRING, \"true\")); the property being explicitly 'false' triggers the throw before the injector is built.","commonSituations":"Clusters upgraded from legacy versions where 3VL was opt-in; ops teams disabling 3VL to reproduce old query results; stale config files carried across upgrades.","solutions":["Remove the property or set it to 'true' in runtime properties","Migrate queries per the linked ANSI SQL null migration doc to get expected results under three-valued logic","Audit dashboards/scheduled queries that relied on legacy boolean NULL semantics and update comparisons (e.g. use IS NOT DISTINCT FROM or explicit NULL checks)"],"exampleFix":"// before\n<removed-3vl-property>=false\n// after\n# property removed (3VL always enabled)","handlingStrategy":"validation","validationCode":"String v = props.getProperty(\"<three-value-logic-property>\");\nif (\"false\".equalsIgnoreCase(v)) throw new IllegalStateException(\"3VL toggle removed; must not be 'false'\");","typeGuard":null,"tryCatchPattern":"try { injector = StartupInjectorBuilder.build(); } catch (ISE e) { if (e.getMessage().contains(\"set to 'false', but has been removed\")) log.error(\"Remove the legacy 3VL flag; see migration doc\"); throw e; }","preventionTips":["Remove obsolete toggles from config templates when the upgrade plan is drafted","Verify query results that depended on legacy boolean-NULL semantics in a staging cluster","Automate a config audit that flags keys absent from current docs"],"tags":["configuration","sql","null-handling","three-valued-logic","migration","startup"],"backgroundTag":"removed-config-option","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}