{"record":{"id":"73ddedc62781c649","repo":"apache/druid","slug":"defensive","errorCode":"defensive","errorMessage":"Engine [%s] is unable to recognize the feature [%s] for availability. This might happen when a newer feature is added without updating all the implementations of SqlEngine(s) to either allow or disallow its availability. Please raise an issue if you encounter this exception while using Druid.","messagePattern":"Engine \\[(.+?)\\] is unable to recognize the feature \\[(.+?)\\] for availability\\. This might happen when a newer feature is added without updating all the implementations of SqlEngine\\(s\\) to either allow or disallow its availability\\. Please raise an issue if you encounter this exception while using Druid\\.","errorType":"error_code","errorClass":"DruidException","httpStatus":null,"severity":"error","filePath":"multi-stage-query/src/main/java/org/apache/druid/msq/sql/MSQTaskSqlEngine.java","lineNumber":173,"sourceCode":"      case TIMESERIES_QUERY:\n      case TOPN_QUERY:\n      case TIME_BOUNDARY_QUERY:\n      case GROUPING_SETS:\n      case ALLOW_TOP_LEVEL_UNION_ALL:\n      case GROUPBY_IMPLICITLY_SORTS:\n        return false;\n      case WINDOW_FUNCTIONS:\n      case WINDOW_LEAF_OPERATOR:\n      case UNNEST:\n      case CAN_SELECT:\n      case CAN_INSERT:\n      case CAN_REPLACE:\n      case READ_EXTERNAL_DATA:\n      case WRITE_EXTERNAL_DATA:\n      case SCAN_ORDER_BY_NON_TIME:\n        return true;\n      default:\n        throw SqlEngines.generateUnrecognizedFeatureException(MSQTaskSqlEngine.class.getSimpleName(), feature);\n    }\n  }\n\n  @Override\n  public QueryMaker buildQueryMakerForSelect(\n      final RelRoot relRoot,\n      final PlannerContext plannerContext\n  )\n  {\n    validateSelect(plannerContext);\n\n    return new MSQTaskQueryMaker(\n        null,\n        overlordClient,\n        plannerContext,\n        relRoot.fields,\n        terminalStageSpecFactory\n    );","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/multi-stage-query/src/main/java/org/apache/druid/msq/sql/MSQTaskSqlEngine.java#L155-L191","documentation":"MSQTaskSqlEngine.featureAvailable hits its default case when asked about a SupportFeature it does not explicitly handle; SqlEngines.generateUnrecognizedFeatureException produces a DruidException (defensive code) saying the engine cannot recognize the feature for availability. Druid treats this as a programming bug: a new SupportFeature enum constant was added without updating every SqlEngine implementation.","triggerScenarios":"Adding a new SupportFeature enum value and running a query through the MSQ task engine without adding the case to MSQTaskSqlEngine.featureAvailable; custom SqlEngine forks enumerating features incompletely.","commonSituations":"Developers extending Druid's SQL engines with new features (e.g. a new CAN_* capability) and only updating some engines; upgrading Druid with custom engine extensions that lag the core enum.","solutions":["Add the new feature constant to MSQTaskSqlEngine.featureAvailable with the correct availability.","Audit every SqlEngine implementation (native, MSQ task, others) for exhaustive switch handling of the enum.","Ensure any custom engine extension is rebuilt against the current Druid version.","File/track an upstream issue if this occurs with an official Druid build, as the message requests."],"exampleFix":"// before\ncase CAN_REPLACE:\ncase READ_EXTERNAL_DATA:\ncase WRITE_EXTERNAL_DATA:\ncase SCAN_ORDER_BY_NON_TIME:\n  return true;\ndefault:\n  throw SqlEngines.generateUnrecognizedFeatureException(...);\n// after\ncase NEW_FEATURE: // newly added SupportFeature\n  return false;\ncase CAN_REPLACE:\n...\n  return true;\ndefault:\n  throw SqlEngines.generateUnrecognizedFeatureException(...);","handlingStrategy":"try-catch","validationCode":"// Exhaustiveness check: ensure every SupportFeature constant is handled\nfor (SupportFeature f : SupportFeature.values()) { engine.featureAvailable(f); } // throws on unhandled constants at startup/test time","typeGuard":null,"tryCatchPattern":"try { engine.featureAvailable(feature); }\ncatch (DruidException e) { if (e.getMessage().contains(\"unable to recognize the feature\")) { throw new IllegalStateException(\"SqlEngine \" + engine + \" is missing a case for \" + feature + \"; update featureAvailable\"); } throw e; }","preventionTips":["When adding SupportFeature constants, update every SqlEngine's featureAvailable in the same PR.","Add an exhaustive-switch test iterating all enum values per engine.","Rebuild custom engine extensions when upgrading Druid."],"tags":["msq","sql-engine","enum","defensive"],"backgroundTag":"unsupported-enum-value","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"}