<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Table does not support batch scan. in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174008#M56794</link>
    <description>&lt;P&gt;1. Is this running on Dedicated compute, and does the job identity have SELECT on the underlying tables or only on the UC views?&lt;/P&gt;&lt;P&gt;Yes, it is Dedicated access mode on DBR 18 (Spark 4.1.0, also tested on DBR 19, spark 4.2). The identity running the query owns the views and the underlying Delta tables, and also has catalog-level privileges (SELECT and ALL PRIVILEGES) through a group. So it has direct SELECT on the base tables, not only on the views.&lt;/P&gt;&lt;P&gt;2. If possible, could you share the Step 2 explain() plan both with and without the checkpoint? That would confirm whether RemoteSparkConnectScan disappears after materialisation.&lt;/P&gt;&lt;P&gt;Both plans are for the Step 1 read (SELECT * from vw_activity_events), shortened to the first 8 columns of each list. Table and column names are changed.&lt;/P&gt;&lt;P&gt;Without the checkpoint:&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;== Parsed Logical Plan ==&lt;BR /&gt;'Project [*]&lt;BR /&gt;+- 'Filter (('activity_type IN (a, b) AND ('occurred_at &amp;gt; 2026-10-13 09:02:00.404)) AND (('occurred_at &amp;lt;= 2026-10-20 06:36:48.614052) AND ('COALESCE('is_automated, false) = false)))&lt;BR /&gt;+- 'UnresolvedRelation [app_dev, vw_activity_events], [], false&lt;BR /&gt;&lt;BR /&gt;== Analyzed Logical Plan ==&lt;BR /&gt;load_date: date, year: int, month: int, day: int, app_id: string, page_view_id: string, actor_key: bigint, user_id: string, ... 161 more fields&lt;BR /&gt;Project [load_date#2396, year#2397, month#2398, day#2399, app_id#2400, page_view_id#2401, actor_key#2402L, user_id#2403, ... 161 more fields]&lt;BR /&gt;+- Filter ((activity_type#2526 IN (a, b) AND (occurred_at#2524 &amp;gt; 2026-10-13 09:02:00.404)) AND ((occurred_at#2524 &amp;lt;= 2026-10-20 06:36:48.614052) AND (coalesce(is_automated#2563, false) = false)))&lt;BR /&gt;+- SubqueryAlias acme_prod.app_dev.vw_activity_events&lt;BR /&gt;+- View (`acme_prod`.`app_dev`.`vw_activity_events`, [load_date#2396, year#2397, month#2398, day#2399, app_id#2400, page_view_id#2401, actor_key#2402L, user_id#2403, ... 161 more fields])&lt;BR /&gt;+- Project [cast(load_date#2756 as date) AS load_date#2396, cast(year#2757 as int) AS year#2397, cast(month#2758 as int) AS month#2398, cast(day#2759 as int) AS day#2399, cast(app_id#2760 as string) AS app_id#2400, cast(page_view_id#2761 as string) AS page_view_id#2401, cast(actor_key#2941L as bigint) AS actor_key#2402L, cast(user_id#2776 as string) AS user_id#2403, ... 161 more fields]&lt;BR /&gt;+- Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, actor_key#2941L, user_id#2776, ... 161 more fields]&lt;BR /&gt;+- Filter NOT (activity_type#2885 = heartbeat)&lt;BR /&gt;+- Join LeftOuter, between(cast(occurred_at#2883 as date), period_start#2954, period_end#2955)&lt;BR /&gt;:- SubqueryAlias e&lt;BR /&gt;: +- SubqueryAlias acme_prod.app_dev.activity_events&lt;BR /&gt;: +- Relation acme_prod.app_dev.activity_events[load_date#2756,year#2757,month#2758,day#2759,app_id#2760,page_view_id#2761,session_id#2762,domain_sessionidx#2763,... 183 more fields] parquet&lt;BR /&gt;+- SubqueryAlias p&lt;BR /&gt;+- SubqueryAlias acme_prod.app_dev.vw_period&lt;BR /&gt;+- RelationV2[period_key#2952L, period_label#2953, period_start#2954, period_end#2955, period_tz#2956] acme_prod.app_dev.vw_period&lt;BR /&gt;&lt;BR /&gt;== Optimized Logical Plan ==&lt;BR /&gt;Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, actor_key#2941L, user_id#2776, ... 161 more fields]&lt;BR /&gt;+- Join LeftOuter, ((cast(occurred_at#2883 as date) &amp;gt;= period_start#2954) AND (cast(occurred_at#2883 as date) &amp;lt;= period_end#2955))&lt;BR /&gt;:- Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, session_id#2762, domain_sessionidx#2763, ... 145 more fields]&lt;BR /&gt;: +- Filter ((isnotnull(activity_type#2885) AND isnotnull(occurred_at#2883)) AND ((((NOT (activity_type#2885 = heartbeat) AND cast(activity_type#2885 as string) INSET a, b) AND (occurred_at#2883 &amp;gt; 2026-10-13 09:02:00.404)) AND (occurred_at#2883 &amp;lt;= 2026-10-20 06:36:48.614052)) AND NOT coalesce(is_automated#2945, false)))&lt;BR /&gt;: +- Relation acme_prod.app_dev.activity_events[load_date#2756,year#2757,month#2758,day#2759,app_id#2760,page_view_id#2761,session_id#2762,domain_sessionidx#2763,... 183 more fields] parquet&lt;BR /&gt;+- RelationV2[period_key#2952L, period_start#2954, period_end#2955] acme_prod.app_dev.vw_period&lt;BR /&gt;&lt;BR /&gt;== Physical Plan ==&lt;BR /&gt;AdaptiveSparkPlan isFinalPlan=false&lt;BR /&gt;+- == Initial Plan ==&lt;BR /&gt;Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, actor_key#2941L, user_id#2776, ... 161 more fields]&lt;BR /&gt;+- BroadcastNestedLoopJoin BuildRight, LeftOuter, ((cast(occurred_at#2883 as date) &amp;gt;= period_start#2954) AND (cast(occurred_at#2883 as date) &amp;lt;= period_end#2955)), true&lt;BR /&gt;:- Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, session_id#2762, domain_sessionidx#2763, ... 145 more fields]&lt;BR /&gt;: +- Filter ((((if (isnotnull(_databricks_internal_edge_computed_column_skip_row#2979)) (_databricks_internal_edge_computed_column_skip_row#2979 = false) else isnotnull(raise_error(DELTA_SKIP_ROW_COLUMN_NOT_FILLED, map(keys: [], values: []), NullType)) AND isnotnull(occurred_at#2883)) AND (occurred_at#2883 &amp;gt; 2026-10-13 09:02:00.404)) AND (occurred_at#2883 &amp;lt;= 2026-10-20 06:36:48.614052)) AND NOT coalesce(is_automated#2945, false))&lt;BR /&gt;: +- FileScan parquet acme_prod.app_dev.activity_events[load_date#2756,app_id#2760,page_view_id#2761,session_id#2762,domain_sessionidx#2763,platform_label#2765,etl_tstamp#2766,collected_at#2767,... 146 more fields] Batched: false, DataFilters: [isnotnull(occurred_at#2883), (occurred_at#2883 &amp;gt; 2026-10-13 09:02:00.404), (occurred_at..., Format: Parquet, Location: PreparedDeltaFileIndex(1 paths)[s3://example-bucket/dev/tenant/master-data/activity_events], PartitionFilters: [isnotnull(activity_type#2885), NOT (activity_type#2885 = heartbeat), cast(activity_type#2885 as string) I..., PushedFilters: [IsNotNull(occurred_at), GreaterThan(occurred_at,2026-10-13 09:02:00.404), LessThanOrEqual(..., ReadSchema: struct&amp;lt;load_date:date,app_id:string,page_view_id:string,session_id:string,domain_sessionidx...&lt;BR /&gt;+- Exchange SinglePartition, EXECUTOR_BROADCAST, [plan_id=726]&lt;BR /&gt;+- Project [period_key#2952L, period_start#2954, period_end#2955]&lt;BR /&gt;+- RemoteSparkConnectScan `acme_prod`.`app_dev`.`vw_period`[period_key#2952L, period_start#2954, period_end#2955] PushedPredicates: [period_start IS NOT NULL, period_end IS NOT NULL], PushedAggregates: [], PushedGroupBys: [], PushedLimits: [], PushedSortOrders: [], PushedSamples: [], PushedJoinedRelations: [], RuntimeFilters: []&lt;BR /&gt;&lt;BR /&gt;== Optimizer Statistics (table names per statistics state) ==&lt;BR /&gt;missing = activity_events&lt;BR /&gt;partial = &lt;BR /&gt;full = &lt;BR /&gt;Corrective actions: consider running the following command on all tables with missing or partial statistics&lt;BR /&gt;ANALYZE TABLE &amp;lt;table-name&amp;gt; COMPUTE STATISTICS FOR ALL COLUMNS&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;vw_period is not expanded. It appears as RelationV2 in the analyzed plan, and in the physical plan it is read by RemoteSparkConnectScan on the broadcast side of the BroadcastNestedLoopJoin. This query runs fine on its own.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;With localCheckpoint(eager=True) on the same DataFrame:&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;== Parsed Logical Plan ==&lt;BR /&gt;LogicalRDD [load_date#3305, year#3306, month#3307, day#3308, app_id#3309, page_view_id#3310, actor_key#3311L, user_id#3312, ... 161 more fields], false&lt;BR /&gt;&lt;BR /&gt;== Analyzed Logical Plan ==&lt;BR /&gt;load_date: date, year: int, month: int, day: int, app_id: string, page_view_id: string, actor_key: bigint, user_id: string, ... 161 more fields&lt;BR /&gt;LogicalRDD [load_date#3305, year#3306, month#3307, day#3308, app_id#3309, page_view_id#3310, actor_key#3311L, user_id#3312, ... 161 more fields], false&lt;BR /&gt;&lt;BR /&gt;== Optimized Logical Plan ==&lt;BR /&gt;LogicalRDD [load_date#3305, year#3306, month#3307, day#3308, app_id#3309, page_view_id#3310, actor_key#3311L, user_id#3312, ... 161 more fields], false&lt;BR /&gt;&lt;BR /&gt;== Physical Plan ==&lt;BR /&gt;Scan ExistingRDD[load_date#3305,year#3306,month#3307,day#3308,app_id#3309,page_view_id#3310,actor_key#3311L,user_id#3312,... 161 more fields]&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;The plan becomes LogicalRDD / Scan ExistingRDD. There is no view node and no RemoteSparkConnectScan, and the Step 2 query on top of it runs normally.&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
    <pubDate>Tue, 20 Oct 2026 07:16:33 GMT</pubDate>
    <dc:creator>harsh120</dc:creator>
    <dc:date>2026-10-20T07:16:33Z</dc:date>
    <item>
      <title>Table does not support batch scan.</title>
      <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/173863#M56783</link>
      <description>&lt;P&gt;After moving our incremental load jobs from DBR 16.4 (Spark 3.5) to DBR 18 (Spark 4.1.0), they fail with this error:&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;[UNSUPPORTED_FEATURE.TABLE_OPERATION] The feature is not supported:
Table `app_dev`.`vw_period` does not support batch scan. Please check the
current catalog and namespace to make sure the qualified table name is
expected, and also check the catalog implementation which is configured
by "spark.sql.catalog". SQLSTATE: 0A000&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&lt;STRONG&gt;vw_period&lt;/STRONG&gt; is a regular Unity Catalog view, and the table under it is a plain external Delta table, not a streaming table, materialized view or pipeline output. The same views, data and code ran without problems on 16.4.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Table and view Defination&lt;/STRONG&gt;&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;-- external Delta table, about 20 rows in total
CREATE TABLE acme_prod.app_dev.calendar_entries (
  entry_id BIGINT, period_key BIGINT, period_label STRING,
  period_start DATE, period_end DATE, period_tz STRING
  -- other columns omitted
) USING DELTA;

CREATE OR REPLACE VIEW acme_prod.app_dev.vw_period AS
SELECT DISTINCT period_key, period_label, period_start, period_end, period_tz
FROM acme_prod.app_dev.calendar_entries;

-- external Delta table, partitioned by activity_type; the real one has about 170 columns
CREATE TABLE acme_prod.app_dev.activity_events (
  activity_id STRING, actor_key BIGINT, activity_type STRING,
  platform_label STRING, session_id STRING,
  occurred_at TIMESTAMP, is_automated BOOLEAN
  -- other columns omitted
) USING DELTA PARTITIONED BY (activity_type);

CREATE OR REPLACE VIEW acme_prod.app_dev.vw_activity_events AS
SELECT e.*, COALESCE(p.period_key, CAST(-1 AS BIGINT)) AS period_key
FROM acme_prod.app_dev.activity_events e
LEFT JOIN acme_prod.app_dev.vw_period p
  ON CAST(e.occurred_at AS DATE) BETWEEN p.period_start AND p.period_end
WHERE e.activity_type &amp;lt;&amp;gt; 'heartbeat';&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&lt;STRONG&gt;What works and what fails&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;The first read works on DBR 18, and isEmpty() and rdd.isEmpty() both return normally on it:&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;src=spark.sql("""
  SELECT * FROM acme_prod.app_dev.vw_activity_events
  WHERE activity_type IN ('a', 'b')
    AND occurred_at &amp;gt;  TIMESTAMP '2026-10-13 09:02:00'
    AND occurred_at &amp;lt;= TIMESTAMP '2026-10-19 12:46:00'
    AND COALESCE(is_automated, false) = false
""")
src.createOrReplaceTempView("events_incr")&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;The next step is where it fails:&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;&lt;SPAN&gt;out = spark.sql("""
  SELECT CONCAT('X_', activity_id) AS event_key, actor_key,
         UPPER(activity_type) AS activity_type, CAST(occurred_at AS DATE) AS event_date,
         period_key,
         MAP('platform_label', platform_label, 'session_id', session_id) AS props
  FROM events_incr
""").filter("actor_key IS NOT NULL")

out.isEmpty()   # raises the error above&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;The plan for the first query is below. Under the outer view, vw_period is not expanded into its SELECT DISTINCT. It shows up as RelationV2 and is read by RemoteSparkConnectScan, while the outer view is expanded normally.&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;== Parsed Logical Plan ==
'Project [*]
+- 'Filter ((activity_type IN (...) AND (occurred_at &amp;gt; 2026-10-13 09:02:00.404))
            AND ((occurred_at &amp;lt;= 2026-10-19 12:46:43.923587)
                 AND (COALESCE(is_automated, false) = false)))
   +- 'UnresolvedRelation [app_dev, vw_activity_events], [], false

== Analyzed Logical Plan ==
Project [...]
+- Filter ((activity_type IN (...) AND (occurred_at &amp;gt; ...)) AND ((occurred_at &amp;lt;= ...) AND (coalesce(is_automated, false) = false)))
   +- SubqueryAlias acme_prod.app_dev.vw_activity_events
      +- View (acme_prod.app_dev.vw_activity_events, [...])
         +- Project [...]
            +- Filter NOT (activity_type = heartbeat)
               +- Join LeftOuter, between(cast(occurred_at as date), period_start, period_end)
                  :- SubqueryAlias acme_prod.app_dev.activity_events
                  :  +- Relation acme_prod.app_dev.activity_events[...] parquet
                  +- SubqueryAlias p
                     +- SubqueryAlias acme_prod.app_dev.vw_period
                        +- RelationV2[period_key, period_label, period_start, period_end, period_tz] acme_prod.app_dev.vw_period

== Optimized Logical Plan ==
Project [...]
+- Join LeftOuter, ((cast(occurred_at as date) &amp;gt;= period_start) AND (cast(occurred_at as date) &amp;lt;= period_end))
   :- Project [...]
   :  +- Filter (activity_type INSET (...) AND occurred_at &amp;gt; ... AND occurred_at &amp;lt;= ... AND NOT coalesce(is_automated, false))
   :     +- Relation acme_prod.app_dev.activity_events[...] parquet
   +- RelationV2[period_key, period_start, period_end] acme_prod.app_dev.vw_period

== Physical Plan ==
AdaptiveSparkPlan isFinalPlan=true
+- BroadcastNestedLoopJoin BuildRight, LeftOuter, ((cast(occurred_at as date) &amp;gt;= period_start) AND (cast(occurred_at as date) &amp;lt;= period_end)), true
   :- FileScan parquet acme_prod.app_dev.activity_events[...]
   :     Batched: false
   :     Location: PreparedDeltaFileIndex(1 paths)[s3://example-bucket/dev/tenant/master-data/activity_events]
   :     PartitionFilters: [isnotnull(activity_type), NOT (activity_type = heartbeat), activity_type INSET (...)]
   :     PushedFilters: [IsNotNull(occurred_at), GreaterThan(occurred_at, ...), LessThanOrEqual(occurred_at, ...)]
   +- Exchange SinglePartition, EXECUTOR_BROADCAST
      +- Project [period_key, period_start, period_end]
         +- RemoteSparkConnectScan acme_prod.app_dev.vw_period[period_key, period_start, period_end]
              PushedPredicates: [period_start IS NOT NULL, period_end IS NOT NULL]
              Runtime row count reported for this side: 5
              Size: 160 bytes&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&lt;STRONG&gt;What I tried&lt;/STRONG&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Setting spark.sql.ansi.enabled to false made no difference.&lt;/LI&gt;&lt;LI&gt;Recreating both views, and using fully qualified names, made no difference. DESCRIBE EXTENDED on both views shows the correct catalog and namespace.&lt;/LI&gt;&lt;LI&gt;Calling localCheckpoint(eager=True) on the first DataFrame, before the second step, lets the whole job run on DBR 18. That is our workaround for now.&lt;/LI&gt;&lt;LI&gt;A second job joins another Delta table to vw_activity_events and adds a transform() over an array column in the same query. It fails the same way. Splitting the join from the transform() with a checkpoint avoids it. I haven’t isolated which expression triggers it.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Is this a known issue in DBR 18? Why is vw_period planned as RelationV2 and read through RemoteSparkConnectScan instead of being expanded, and what makes the second query’s scan fail when the first query’s succeeds? Is there a setting or recommended pattern to use until a fix is out?&lt;/P&gt;</description>
      <pubDate>Mon, 19 Oct 2026 13:15:27 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/173863#M56783</guid>
      <dc:creator>harsh120</dc:creator>
      <dc:date>2026-10-19T13:15:27Z</dc:date>
    </item>
    <item>
      <title>Re: Table does not support batch scan.</title>
      <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/173879#M56784</link>
      <description>&lt;P&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/235822"&gt;@harsh120&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried reproducing this with a similar setup using nested permanent Unity Catalog views, including SELECT DISTINCT, a date-range LEFT JOIN, a temporary view and the subsequent MAP()/filter transformations with isEmpty().&lt;/P&gt;&lt;P&gt;Both steps passed on Databricks Serverless (Spark 4.2.0), including with ANSI enabled. The execution plans expanded the UC views into the underlying Delta tables, using PhotonScan and PhotonBroadcastNestedLoopJoin.&lt;/P&gt;&lt;P&gt;One notable difference from your DBR 18 plan is RemoteSparkConnectScan / RelationV2 for vw_period, rather than expansion into the underlying Delta table.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;Databricks &lt;A href="https://docs.databricks.com/aws/en/compute/single-user-fgac" target="_self"&gt;documents&lt;/A&gt; RemoteSparkConnectScan&lt;/STRONG&gt; in the context of fine-grained access control on Dedicated compute.&lt;/P&gt;&lt;P&gt;Since localCheckpoint(eager=True) works, I suspect the issue may involve how DBR 18 replans the nested view through this remote scan during Step 2, rather than the MAP() expression or ANSI mode itself.&lt;/P&gt;&lt;P&gt;Few questions to understand further:&lt;/P&gt;&lt;P&gt;1. Is this running on Dedicated compute, and does the job identity have SELECT on the underlying tables or only on the UC views?&lt;/P&gt;&lt;P&gt;2. If possible, could you share the Step 2 explain() plan both with and without the checkpoint? That would confirm whether RemoteSparkConnectScan disappears after materialisation.&lt;/P&gt;</description>
      <pubDate>Mon, 19 Oct 2026 15:39:44 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/173879#M56784</guid>
      <dc:creator>data_pulse</dc:creator>
      <dc:date>2026-10-19T15:39:44Z</dc:date>
    </item>
    <item>
      <title>Re: Table does not support batch scan.</title>
      <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/173963#M56788</link>
      <description>&lt;P&gt;Hi harsh120, building on data_pulse's remote-scan observation, I would use localCheckpoint's success as a plan boundary to investigate, rather than proof that MAP is unsupported or that a particular DBR fix exists.&lt;/P&gt;&lt;P&gt;Keep the same compute and run-as identity, then add the second query's pieces incrementally: required base columns, period_key, CONCAT/UPPER/date expressions, and finally MAP plus the actor filter. Trigger the same isEmpty action after each addition and retain the failing plan. This should narrow which change exposes the remote scan failure.&lt;/P&gt;&lt;P&gt;One caution with the workaround: Spark documents local checkpoints as executor-cache-backed and unreliable. Test executor loss and rerun behavior before treating this as a recovery boundary. I would avoid broadening base-table permissions just to eliminate the scan.&lt;/P&gt;&lt;P&gt;For support, retain the exact DBR build, access mode, sanitized view definitions and paired failing/checkpointed plans. I cannot confirm a published fix for this exact case.&lt;/P&gt;&lt;P&gt;References:&lt;BR /&gt;&lt;A href="https://docs.databricks.com/aws/en/compute/single-user-fgac" target="_blank"&gt;https://docs.databricks.com/aws/en/compute/single-user-fgac&lt;/A&gt;&lt;BR /&gt;&lt;A href="https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.localCheckpoint.html" target="_blank"&gt;https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.localCheckpoint.html&lt;/A&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 19 Oct 2026 22:34:55 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/173963#M56788</guid>
      <dc:creator>Jen_Evangelista</dc:creator>
      <dc:date>2026-10-19T22:34:55Z</dc:date>
    </item>
    <item>
      <title>Re: Table does not support batch scan.</title>
      <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174008#M56794</link>
      <description>&lt;P&gt;1. Is this running on Dedicated compute, and does the job identity have SELECT on the underlying tables or only on the UC views?&lt;/P&gt;&lt;P&gt;Yes, it is Dedicated access mode on DBR 18 (Spark 4.1.0, also tested on DBR 19, spark 4.2). The identity running the query owns the views and the underlying Delta tables, and also has catalog-level privileges (SELECT and ALL PRIVILEGES) through a group. So it has direct SELECT on the base tables, not only on the views.&lt;/P&gt;&lt;P&gt;2. If possible, could you share the Step 2 explain() plan both with and without the checkpoint? That would confirm whether RemoteSparkConnectScan disappears after materialisation.&lt;/P&gt;&lt;P&gt;Both plans are for the Step 1 read (SELECT * from vw_activity_events), shortened to the first 8 columns of each list. Table and column names are changed.&lt;/P&gt;&lt;P&gt;Without the checkpoint:&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;== Parsed Logical Plan ==&lt;BR /&gt;'Project [*]&lt;BR /&gt;+- 'Filter (('activity_type IN (a, b) AND ('occurred_at &amp;gt; 2026-10-13 09:02:00.404)) AND (('occurred_at &amp;lt;= 2026-10-20 06:36:48.614052) AND ('COALESCE('is_automated, false) = false)))&lt;BR /&gt;+- 'UnresolvedRelation [app_dev, vw_activity_events], [], false&lt;BR /&gt;&lt;BR /&gt;== Analyzed Logical Plan ==&lt;BR /&gt;load_date: date, year: int, month: int, day: int, app_id: string, page_view_id: string, actor_key: bigint, user_id: string, ... 161 more fields&lt;BR /&gt;Project [load_date#2396, year#2397, month#2398, day#2399, app_id#2400, page_view_id#2401, actor_key#2402L, user_id#2403, ... 161 more fields]&lt;BR /&gt;+- Filter ((activity_type#2526 IN (a, b) AND (occurred_at#2524 &amp;gt; 2026-10-13 09:02:00.404)) AND ((occurred_at#2524 &amp;lt;= 2026-10-20 06:36:48.614052) AND (coalesce(is_automated#2563, false) = false)))&lt;BR /&gt;+- SubqueryAlias acme_prod.app_dev.vw_activity_events&lt;BR /&gt;+- View (`acme_prod`.`app_dev`.`vw_activity_events`, [load_date#2396, year#2397, month#2398, day#2399, app_id#2400, page_view_id#2401, actor_key#2402L, user_id#2403, ... 161 more fields])&lt;BR /&gt;+- Project [cast(load_date#2756 as date) AS load_date#2396, cast(year#2757 as int) AS year#2397, cast(month#2758 as int) AS month#2398, cast(day#2759 as int) AS day#2399, cast(app_id#2760 as string) AS app_id#2400, cast(page_view_id#2761 as string) AS page_view_id#2401, cast(actor_key#2941L as bigint) AS actor_key#2402L, cast(user_id#2776 as string) AS user_id#2403, ... 161 more fields]&lt;BR /&gt;+- Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, actor_key#2941L, user_id#2776, ... 161 more fields]&lt;BR /&gt;+- Filter NOT (activity_type#2885 = heartbeat)&lt;BR /&gt;+- Join LeftOuter, between(cast(occurred_at#2883 as date), period_start#2954, period_end#2955)&lt;BR /&gt;:- SubqueryAlias e&lt;BR /&gt;: +- SubqueryAlias acme_prod.app_dev.activity_events&lt;BR /&gt;: +- Relation acme_prod.app_dev.activity_events[load_date#2756,year#2757,month#2758,day#2759,app_id#2760,page_view_id#2761,session_id#2762,domain_sessionidx#2763,... 183 more fields] parquet&lt;BR /&gt;+- SubqueryAlias p&lt;BR /&gt;+- SubqueryAlias acme_prod.app_dev.vw_period&lt;BR /&gt;+- RelationV2[period_key#2952L, period_label#2953, period_start#2954, period_end#2955, period_tz#2956] acme_prod.app_dev.vw_period&lt;BR /&gt;&lt;BR /&gt;== Optimized Logical Plan ==&lt;BR /&gt;Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, actor_key#2941L, user_id#2776, ... 161 more fields]&lt;BR /&gt;+- Join LeftOuter, ((cast(occurred_at#2883 as date) &amp;gt;= period_start#2954) AND (cast(occurred_at#2883 as date) &amp;lt;= period_end#2955))&lt;BR /&gt;:- Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, session_id#2762, domain_sessionidx#2763, ... 145 more fields]&lt;BR /&gt;: +- Filter ((isnotnull(activity_type#2885) AND isnotnull(occurred_at#2883)) AND ((((NOT (activity_type#2885 = heartbeat) AND cast(activity_type#2885 as string) INSET a, b) AND (occurred_at#2883 &amp;gt; 2026-10-13 09:02:00.404)) AND (occurred_at#2883 &amp;lt;= 2026-10-20 06:36:48.614052)) AND NOT coalesce(is_automated#2945, false)))&lt;BR /&gt;: +- Relation acme_prod.app_dev.activity_events[load_date#2756,year#2757,month#2758,day#2759,app_id#2760,page_view_id#2761,session_id#2762,domain_sessionidx#2763,... 183 more fields] parquet&lt;BR /&gt;+- RelationV2[period_key#2952L, period_start#2954, period_end#2955] acme_prod.app_dev.vw_period&lt;BR /&gt;&lt;BR /&gt;== Physical Plan ==&lt;BR /&gt;AdaptiveSparkPlan isFinalPlan=false&lt;BR /&gt;+- == Initial Plan ==&lt;BR /&gt;Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, actor_key#2941L, user_id#2776, ... 161 more fields]&lt;BR /&gt;+- BroadcastNestedLoopJoin BuildRight, LeftOuter, ((cast(occurred_at#2883 as date) &amp;gt;= period_start#2954) AND (cast(occurred_at#2883 as date) &amp;lt;= period_end#2955)), true&lt;BR /&gt;:- Project [load_date#2756, year#2757, month#2758, day#2759, app_id#2760, page_view_id#2761, session_id#2762, domain_sessionidx#2763, ... 145 more fields]&lt;BR /&gt;: +- Filter ((((if (isnotnull(_databricks_internal_edge_computed_column_skip_row#2979)) (_databricks_internal_edge_computed_column_skip_row#2979 = false) else isnotnull(raise_error(DELTA_SKIP_ROW_COLUMN_NOT_FILLED, map(keys: [], values: []), NullType)) AND isnotnull(occurred_at#2883)) AND (occurred_at#2883 &amp;gt; 2026-10-13 09:02:00.404)) AND (occurred_at#2883 &amp;lt;= 2026-10-20 06:36:48.614052)) AND NOT coalesce(is_automated#2945, false))&lt;BR /&gt;: +- FileScan parquet acme_prod.app_dev.activity_events[load_date#2756,app_id#2760,page_view_id#2761,session_id#2762,domain_sessionidx#2763,platform_label#2765,etl_tstamp#2766,collected_at#2767,... 146 more fields] Batched: false, DataFilters: [isnotnull(occurred_at#2883), (occurred_at#2883 &amp;gt; 2026-10-13 09:02:00.404), (occurred_at..., Format: Parquet, Location: PreparedDeltaFileIndex(1 paths)[s3://example-bucket/dev/tenant/master-data/activity_events], PartitionFilters: [isnotnull(activity_type#2885), NOT (activity_type#2885 = heartbeat), cast(activity_type#2885 as string) I..., PushedFilters: [IsNotNull(occurred_at), GreaterThan(occurred_at,2026-10-13 09:02:00.404), LessThanOrEqual(..., ReadSchema: struct&amp;lt;load_date:date,app_id:string,page_view_id:string,session_id:string,domain_sessionidx...&lt;BR /&gt;+- Exchange SinglePartition, EXECUTOR_BROADCAST, [plan_id=726]&lt;BR /&gt;+- Project [period_key#2952L, period_start#2954, period_end#2955]&lt;BR /&gt;+- RemoteSparkConnectScan `acme_prod`.`app_dev`.`vw_period`[period_key#2952L, period_start#2954, period_end#2955] PushedPredicates: [period_start IS NOT NULL, period_end IS NOT NULL], PushedAggregates: [], PushedGroupBys: [], PushedLimits: [], PushedSortOrders: [], PushedSamples: [], PushedJoinedRelations: [], RuntimeFilters: []&lt;BR /&gt;&lt;BR /&gt;== Optimizer Statistics (table names per statistics state) ==&lt;BR /&gt;missing = activity_events&lt;BR /&gt;partial = &lt;BR /&gt;full = &lt;BR /&gt;Corrective actions: consider running the following command on all tables with missing or partial statistics&lt;BR /&gt;ANALYZE TABLE &amp;lt;table-name&amp;gt; COMPUTE STATISTICS FOR ALL COLUMNS&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;vw_period is not expanded. It appears as RelationV2 in the analyzed plan, and in the physical plan it is read by RemoteSparkConnectScan on the broadcast side of the BroadcastNestedLoopJoin. This query runs fine on its own.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;With localCheckpoint(eager=True) on the same DataFrame:&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;DIV&gt;&lt;PRE&gt;== Parsed Logical Plan ==&lt;BR /&gt;LogicalRDD [load_date#3305, year#3306, month#3307, day#3308, app_id#3309, page_view_id#3310, actor_key#3311L, user_id#3312, ... 161 more fields], false&lt;BR /&gt;&lt;BR /&gt;== Analyzed Logical Plan ==&lt;BR /&gt;load_date: date, year: int, month: int, day: int, app_id: string, page_view_id: string, actor_key: bigint, user_id: string, ... 161 more fields&lt;BR /&gt;LogicalRDD [load_date#3305, year#3306, month#3307, day#3308, app_id#3309, page_view_id#3310, actor_key#3311L, user_id#3312, ... 161 more fields], false&lt;BR /&gt;&lt;BR /&gt;== Optimized Logical Plan ==&lt;BR /&gt;LogicalRDD [load_date#3305, year#3306, month#3307, day#3308, app_id#3309, page_view_id#3310, actor_key#3311L, user_id#3312, ... 161 more fields], false&lt;BR /&gt;&lt;BR /&gt;== Physical Plan ==&lt;BR /&gt;Scan ExistingRDD[load_date#3305,year#3306,month#3307,day#3308,app_id#3309,page_view_id#3310,actor_key#3311L,user_id#3312,... 161 more fields]&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;The plan becomes LogicalRDD / Scan ExistingRDD. There is no view node and no RemoteSparkConnectScan, and the Step 2 query on top of it runs normally.&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 20 Oct 2026 07:16:33 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174008#M56794</guid>
      <dc:creator>harsh120</dc:creator>
      <dc:date>2026-10-20T07:16:33Z</dc:date>
    </item>
    <item>
      <title>Re: Table does not support batch scan.</title>
      <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174012#M56795</link>
      <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="harsh120_0-1792479807661.png" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/32379iE6952C295787302A/image-size/medium?v=v2&amp;amp;px=400" role="button" title="harsh120_0-1792479807661.png" alt="harsh120_0-1792479807661.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;I also asked Databricks Genie about it, and it described this as a likely bug. I know its answers are not reliable, but it suggests the behavior is unexpected.&lt;BR /&gt;&lt;BR /&gt;For now we dowgraded to DBR 16.4&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 20 Oct 2026 07:23:51 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174012#M56795</guid>
      <dc:creator>harsh120</dc:creator>
      <dc:date>2026-10-20T07:23:51Z</dc:date>
    </item>
    <item>
      <title>Re: Table does not support batch scan.</title>
      <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174268#M56826</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/235822"&gt;@harsh120&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;The &lt;/SPAN&gt;&lt;SPAN&gt;RemoteSparkConnectScan&lt;/SPAN&gt;&lt;SPAN&gt; in the execution plan is an important clue. On Dedicated compute, Databricks can delegate queries involving fine-grained access controls to serverless compute, which explains why a remote scan may appear. However, since the underlying view and tables have no reported FGAC restrictions, I wouldn't assume this is the root cause without further validation.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Since &lt;/SPAN&gt;&lt;SPAN&gt;localCheckpoint(eager=True)&lt;/SPAN&gt;&lt;SPAN&gt; resolves the issue by materializing the DataFrame and removing the remote scan from the subsequent plan, I'd compare the failing and successful execution plans and check whether the behavior is specific to DBR 18/19.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;As a workaround, consider materializing the intermediate result to a durable staging Delta table if appropriate for the incremental pipeline. Unlike &lt;/SPAN&gt;&lt;SPAN&gt;localCheckpoint&lt;/SPAN&gt;&lt;SPAN&gt;, this provides a more reliable recovery boundary.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;It would be useful to confirm whether Databricks has identified this as a runtime regression and whether a fix or recommended workaround is available.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 22 Oct 2026 08:05:04 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174268#M56826</guid>
      <dc:creator>Aravind_Reddy</dc:creator>
      <dc:date>2026-10-22T08:05:04Z</dc:date>
    </item>
    <item>
      <title>Re: Table does not support batch scan.</title>
      <link>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174364#M56841</link>
      <description>&lt;P&gt;Hello &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/235822"&gt;@harsh120&lt;/a&gt;, I took a look at both internal and external documentation and here is what I found.&lt;/P&gt;
&lt;P&gt;Building on &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/250262"&gt;@data_pulse&lt;/a&gt; and &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/266991"&gt;@Jen_Evangelista&lt;/a&gt;: &lt;CODE&gt;RemoteSparkConnectScan&lt;/CODE&gt; is the key clue, and this doesn't look like &lt;CODE&gt;MAP()&lt;/CODE&gt;, &lt;CODE&gt;isEmpty()&lt;/CODE&gt;, or ANSI mode being unsupported on their own.&lt;/P&gt;
&lt;P&gt;On Dedicated compute, Databricks delegates part of a query to serverless compute when fine-grained access control is involved, and that delegation shows up in the plan as &lt;CODE&gt;RemoteSparkConnectScan&lt;/CODE&gt;. The documented triggers are dynamic views, tables with row filters or column masks, materialized views, streaming tables, and views over tables the querying user lacks SELECT on. None of those should apply to &lt;CODE&gt;vw_period&lt;/CODE&gt;, since your identity owns &lt;CODE&gt;calendar_entries&lt;/CODE&gt; and has SELECT on it directly. 16.4 inlined the view; 18 and 19 route it remotely while expanding &lt;CODE&gt;vw_activity_events&lt;/CODE&gt; normally. I couldn't find a release note or doc that explains why a nested view would be treated differently from the outer one.&lt;/P&gt;
&lt;P&gt;The error adds a second clue. "Does not support batch scan" is Spark's &lt;CODE&gt;UNSUPPORTED_FEATURE.TABLE_OPERATION&lt;/CODE&gt; message for a DataSource V2 table object that doesn't implement the readable interface. Your first query got a readable remote table; the second, resolved through the &lt;CODE&gt;events_incr&lt;/CODE&gt; temp view, got one it couldn't read. Same view, different outcome depending on how the plan is reached. That's a planner inconsistency on the remote-filtering path, which lines up with Jen's point about treating the checkpoint as a plan boundary rather than evidence about any specific expression. I can't confirm a published fix for this case, so I'd open a support ticket with the two explain plans you already have, the exact runtime build string, and the fact that it reproduces on 18 and 19 but not 16.4. One housekeeping item first: DBR 18 now ships updates as dated entries that clusters pick up on restart, so make sure the cluster has been restarted recently and record the build you're on.&lt;/P&gt;
&lt;P&gt;Checks that either confirm the mismatch or expose a legitimate trigger:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;CODE&gt;EXPLAIN SELECT * FROM acme_prod.app_dev.vw_period&lt;/CODE&gt; on its own on the DBR 18 cluster. If a standalone read shows &lt;CODE&gt;RemoteSparkConnectScan&lt;/CODE&gt;, the routing decision is about the view itself, not the nesting.&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;SHOW CREATE TABLE&lt;/CODE&gt; on the view, plus &lt;CODE&gt;acme_prod.information_schema.row_filters&lt;/CODE&gt; and &lt;CODE&gt;column_masks&lt;/CODE&gt; for &lt;CODE&gt;calendar_entries&lt;/CODE&gt;, and a look for any ABAC policy at the catalog or schema level that targets a tag on one of its columns. ABAC attaches above the table, so a table can pick up a mask without anyone touching its definition.&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;system.billing.usage&lt;/CODE&gt; filtered to &lt;CODE&gt;billing_origin_product = 'FINE_GRAINED_ACCESS_CONTROL'&lt;/CODE&gt; for the job's run-as identity. If the cluster is paying serverless DBUs to read a 20-row view you own, that's a cost problem on top of the failure and good evidence for the ticket.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;On workarounds, you have cleaner options than &lt;CODE&gt;localCheckpoint&lt;/CODE&gt;. Jen's caution stands: local checkpoints live in executor storage and don't survive executor loss. In rough order of how clean they are:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Remove the nesting. &lt;CODE&gt;vw_period&lt;/CODE&gt; is a &lt;CODE&gt;SELECT DISTINCT&lt;/CODE&gt; projection, so fold it into &lt;CODE&gt;vw_activity_events&lt;/CODE&gt; as a subquery over &lt;CODE&gt;calendar_entries&lt;/CODE&gt;. Base tables you have SELECT on don't take the remote path.&lt;/LI&gt;
&lt;LI&gt;Skip the temp view hop and keep chaining on &lt;CODE&gt;src&lt;/CODE&gt; (&lt;CODE&gt;src.selectExpr(...).filter(...)&lt;/CODE&gt;). The failure appears when the plan goes through the temp view a second time, so this is a cheap test, though I haven't verified it.&lt;/LI&gt;
&lt;LI&gt;If you need a materialization boundary, write the slice to a Delta staging table, or use &lt;CODE&gt;checkpoint(eager=True)&lt;/CODE&gt; with &lt;CODE&gt;sc.setCheckpointDir&lt;/CODE&gt; pointed at a Unity Catalog volume, which is supported on Dedicated compute and restart-safe.&lt;/LI&gt;
&lt;LI&gt;Run the minimal repro on Standard access mode or serverless. Standard enforces fine-grained access natively with no remote scan, and data_pulse's repro passed on serverless. If it passes there and fails on Dedicated, that isolates the issue to the remote-filtering path.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Downgrading to 16.4 is a reasonable short-term move; it's LTS through May 2028. I'd still file the ticket, since engineering is the only group that can explain the routing change.&lt;/P&gt;
&lt;P&gt;References:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Fine-grained access control on dedicated compute: &lt;A href="https://docs.databricks.com/aws/en/compute/single-user-fgac" target="_blank"&gt;https://docs.databricks.com/aws/en/compute/single-user-fgac&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Dedicated compute requirements and limitations: &lt;A href="https://docs.databricks.com/aws/en/compute/dedicated-limitations" target="_blank"&gt;https://docs.databricks.com/aws/en/compute/dedicated-limitations&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Access modes: &lt;A href="https://docs.databricks.com/aws/en/compute/configure#access-mode" target="_blank"&gt;https://docs.databricks.com/aws/en/compute/configure#access-mode&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;ABAC requirements and limitations: &lt;A href="https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac/requirements" target="_blank"&gt;https://docs.databricks.com/aws/en/data-governance/unity-catalog/abac/requirements&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Databricks Runtime 18 LTS release notes: &lt;A href="https://docs.databricks.com/aws/en/release-notes/runtime/18" target="_blank"&gt;https://docs.databricks.com/aws/en/release-notes/runtime/18&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;Databricks Runtime support lifecycles: &lt;A href="https://docs.databricks.com/aws/en/release-notes/runtime/databricks-runtime-ver" target="_blank"&gt;https://docs.databricks.com/aws/en/release-notes/runtime/databricks-runtime-ver&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;DataFrame checkpoints in volumes: &lt;A href="https://docs.databricks.com/aws/en/volumes/volume-files#dataframe-checkpoints" target="_blank"&gt;https://docs.databricks.com/aws/en/volumes/volume-files#dataframe-checkpoints&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;PySpark DataFrame.checkpoint: &lt;A href="https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.checkpoint.html" target="_blank"&gt;https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.checkpoint.html&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;PySpark DataFrame.localCheckpoint: &lt;A href="https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.localCheckpoint.html" target="_blank"&gt;https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.DataFrame.localCheckpoint.html&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Regards,&lt;BR /&gt;Louis&lt;/P&gt;</description>
      <pubDate>Thu, 22 Oct 2026 19:09:11 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/table-does-not-support-batch-scan/m-p/174364#M56841</guid>
      <dc:creator>Louis_Frolio</dc:creator>
      <dc:date>2026-10-22T19:09:11Z</dc:date>
    </item>
  </channel>
</rss>

