{"record":{"id":"58eac01422921a29","repo":"apache/druid","slug":"cannot-create-bloom-filter-s-for-invalid-column-t","errorCode":null,"errorMessage":"Cannot create bloom filter %s for invalid column type [%s]","messagePattern":"Cannot create bloom filter (.+?) for invalid column type \\[(.+?)\\]","errorType":"exception","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"extensions-core/druid-bloom-filter/src/main/java/org/apache/druid/query/aggregation/bloom/BloomFilterAggregatorFactory.java","lineNumber":292,"sourceCode":"              columnFactory.makeColumnValueSelector(field.getDimension()),\n              maxNumEntries,\n              onHeap\n          );\n        case DOUBLE:\n          return new DoubleBloomFilterAggregator(\n              columnFactory.makeColumnValueSelector(field.getDimension()),\n              maxNumEntries,\n              onHeap\n          );\n        case COMPLEX:\n          // in an ideal world, we would check complex type, but until then assume it's a bloom filter\n          return new BloomFilterMergeAggregator(\n              columnFactory.makeColumnValueSelector(field.getDimension()),\n              maxNumEntries,\n              onHeap\n          );\n        default:\n          throw new IAE(\n              \"Cannot create bloom filter %s for invalid column type [%s]\",\n              onHeap ? \"aggregator\" : \"buffer aggregator\",\n              capabilities.asTypeString()\n          );\n      }\n    } else {\n      // No column capabilities, try to guess based on selector type.\n      BaseNullableColumnValueSelector selector = columnFactory.makeColumnValueSelector(field.getDimension());\n\n      if (selector instanceof NilColumnValueSelector) {\n        return new NoopBloomFilterAggregator(maxNumEntries, onHeap);\n      } else if (selector instanceof DimensionSelector) {\n        return new StringBloomFilterAggregator((DimensionSelector) selector, maxNumEntries, onHeap);\n      } else {\n        // Use fallback 'object' aggregator.\n        return new ObjectBloomFilterAggregator(\n            columnFactory.makeColumnValueSelector(field.getDimension()),\n            maxNumEntries,","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/druid-bloom-filter/src/main/java/org/apache/druid/query/aggregation/bloom/BloomFilterAggregatorFactory.java#L274-L310","documentation":"factorizeInternal() switches on the column capabilities (type) of the field being aggregated. Bloom filters can only aggregate string-like or complex bloom-filter columns; a column with an unsupported type (e.g. long/double/numeric) hits the default branch and throws this IllegalArgumentException naming the column type.","triggerScenarios":"Running a query with a 'bloom' aggregator on a dimension whose underlying column type is not STRING (or the bloom-filter complex type), e.g. aggregating a numeric (long/double/float) column or a schemaless/mismatched column; calling factorize()/factorizeBuffered() on a ColumnSelectorFactory whose capabilities.asTypeString() reports VALUE_TYPE_NUMERIC or similar.","commonSituations":"Querying a numeric metric column with a bloom aggregator by mistake; schema evolved so the column is now numeric; typo'd dimension resolving to the wrong column; schemaless ingestion auto-detected numbers where strings were expected.","solutions":["Aggregate a STRING-typed column: cast or add a transform/expression in the query, e.g. use \"type\": \"default\" dimension with an expression like CAST(col AS STRING) via an ExpressionDimensionSpec","Fix ingestion to store the column as string if bloom filtering on it is required","Verify the dimension name points to the intended column and check its type via segment metadata query","Use the SQL layer with BLOOM_FILTER_AGG and CAST(col, 'VARCHAR')"],"exampleFix":"// before\n{\"type\": \"bloom\", \"name\": \"bf\", \"field\": {\"type\": \"default\", \"dimension\": \"user_id_long\"}} // numeric column\n// after\n{\"type\": \"bloom\", \"name\": \"bf\", \"field\": {\"type\": \"expression\", \"expression\": \"CAST(user_id_long AS VARCHAR)\", \"dimension\": \"user_id_str\"}}","handlingStrategy":"validation","validationCode":"// Check column type before running the bloom aggregation (segment metadata query)\n// SELECT column, dataType FROM sys.segments ... or use SegmentMetadataQuery; require VALUE_TYPE_STRING\nboolean ok = \"STRING\".equals(capabilities.getType().toString());","typeGuard":null,"tryCatchPattern":"try {\n  aggregator = factory.factorize(selectorFactory);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().contains(\"invalid column type\")) {\n    // re-plan query with a cast/expression dimension to STRING\n  } else throw e;\n}","preventionTips":["Run a SegmentMetadataQuery (or SQL 'SELECT \"dataType\" FROM information_schema.columns') to confirm the column is STRING before bloom aggregation","CAST numeric columns to VARCHAR (expression dimension) when needed","Verify dimension names to avoid resolving to wrong-typed columns"],"tags":["druid","bloom-filter","invalid-column-type","aggregation"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}