<?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: Serverless Scala JAR: foreachBatch fails with RST_STREAM PROTOCOL_ERROR in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/serverless-scala-jar-foreachbatch-fails-with-rst-stream-protocol/m-p/164951#M55362</link>
    <description>&lt;P data-pm-slice="1 1 []"&gt;On (1): the docs don't gate Scala &lt;CODE&gt;foreachBatch&lt;/CODE&gt; on serverless. &lt;A href="https://docs.databricks.com/aws/en/dev-tools/databricks-connect/scala/limitations" target="_blank"&gt;Limitations with Databricks Connect for Scala&lt;/A&gt; lists streaming &lt;CODE&gt;foreachBatch&lt;/CODE&gt; as unavailable only on Databricks Runtime 13.3 LTS and below, and &lt;A href="https://docs.databricks.com/aws/en/compute/serverless/limitations" target="_blank"&gt;serverless limitations&lt;/A&gt; names only &lt;CODE&gt;Trigger.ProcessingTime&lt;/CODE&gt; and &lt;CODE&gt;Trigger.Continuous&lt;/CODE&gt; as blocked triggers. Serverless Scala and Java JAR jobs are in Public Preview. I'm reading published docs here, not speaking for support.&lt;/P&gt;
&lt;P&gt;On (2): I can't find any published Databricks doc or KB that names &lt;CODE&gt;RST_STREAM&lt;/CODE&gt; or &lt;CODE&gt;PROTOCOL_ERROR&lt;/CODE&gt;, so I wouldn't put a label on it from out here. One thing worth raising with support: &lt;CODE&gt;[UDF_ERROR](&lt;A href="https://docs.databricks.com/aws/en/error-messages/udf-error-error-class" target="_blank"&gt;https://docs.databricks.com/aws/en/error-messages/udf-error-error-class&lt;/A&gt;)&lt;/CODE&gt; has a dedicated &lt;CODE&gt;ENV_LOST&lt;/CODE&gt; sub-condition for an execution environment that was lost mid-run, and you're getting &lt;CODE&gt;INTERNAL&lt;/CODE&gt; instead. Whether that distinction is meaningful here is a question for whoever picks up the ticket. Your empty no-op result already rules out the merge logic.&lt;/P&gt;
&lt;P&gt;On (3), three things before the case:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;Make sure your application logs are actually being emitted. On serverless, the SLF4J logging API defaults to a no-op backend and application log output is silently discarded unless you add the &lt;CODE&gt;log4j-slf4j2-impl&lt;/CODE&gt; bridge matching the &lt;CODE&gt;log4j-api&lt;/CODE&gt; version in your environment version (2.20.0 on environment version 5). See &lt;A href="https://docs.databricks.com/aws/en/jobs/jar-create" target="_blank"&gt;Configure logging for serverless compute&lt;/A&gt;. One note on the &lt;CODE&gt;log4j.logger.org.apache.spark.sql.connect=DEBUG&lt;/CODE&gt; suggestion above: Spark logs aren't available on serverless, only client-side application logs, &lt;A href="https://docs.databricks.com/aws/en/spark/conf" target="_blank"&gt;only six Spark properties are settable&lt;/A&gt; and none are log4j-related, and changing the log4j level through &lt;CODE&gt;SparkContext&lt;/CODE&gt; is listed as unavailable. Use the query profile in place of the Spark UI.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Match Scala, JDK, and your Spark API dependency to your &lt;A href="https://docs.databricks.com/aws/en/release-notes/serverless/" target="_blank"&gt;environment version&lt;/A&gt;. You mentioned you're not building against Databricks Connect; &lt;CODE&gt;spark-sql-api&lt;/CODE&gt; is a documented alternative, but Databricks recommends &lt;CODE&gt;databricks-connect&lt;/CODE&gt; marked &lt;CODE&gt;provided&lt;/CODE&gt;, so that's worth ruling out. Don't bundle &lt;CODE&gt;log4j-api&lt;/CODE&gt; or &lt;CODE&gt;log4j-core&lt;/CODE&gt;.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Isolate &lt;CODE&gt;foreachBatch&lt;/CODE&gt; itself. Swap Kinesis for a small Delta table, &lt;CODE&gt;Trigger.AvailableNow()&lt;/CODE&gt;, empty &lt;CODE&gt;foreachBatch&lt;/CODE&gt;, single-class JAR. Delta is a documented serverless streaming source, so a failure there isolates &lt;CODE&gt;foreachBatch&lt;/CODE&gt; cleanly.&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;If that still fails, it's a clean repro to attach to a support case. On fallback, note that standard access mode also runs on Spark Connect; &lt;A href="https://docs.databricks.com/aws/en/jobs/jar-create" target="_blank"&gt;dedicated compute&lt;/A&gt; is the mode that uses the classic Spark architecture.&lt;/P&gt;</description>
    <pubDate>Wed, 05 Aug 2026 15:05:23 GMT</pubDate>
    <dc:creator>AbhilashNagilla</dc:creator>
    <dc:date>2026-08-05T15:05:23Z</dc:date>
    <item>
      <title>Serverless Scala JAR: foreachBatch fails with RST_STREAM PROTOCOL_ERROR</title>
      <link>https://community.databricks.com/t5/data-engineering/serverless-scala-jar-foreachbatch-fails-with-rst-stream-protocol/m-p/164827#M55346</link>
      <description>&lt;P&gt;Hi everyone,&lt;/P&gt;&lt;P&gt;We're migrating a Scala Structured Streaming application (Kinesis → Delta) from classic compute to Databricks Serverless Jobs for cost optimization. During the migration, we're consistently seeing what appears to be a Spark Connect / gRPC transport issue whenever&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is used.&lt;/P&gt;&lt;H3&gt;Environment&lt;/H3&gt;&lt;UL&gt;&lt;LI&gt;&lt;STRONG&gt;Compute:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Databricks Serverless Jobs (Spark JAR task)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Language:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Scala (big JAR entry point; not a notebook and not using Databricks Connect)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Trigger:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Trigger.AvailableNow()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(required on Serverless)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Source:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Databricks native Kinesis connector with Unity Catalog service credential&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Checkpoint:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;S3 checkpoint location&lt;/LI&gt;&lt;LI&gt;Failed&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;executions show empty start offsets (batch never commits)&lt;/LI&gt;&lt;LI&gt;&lt;STRONG&gt;Spark config:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;spark.sql.shuffle.partitions=auto&lt;/LI&gt;&lt;/UL&gt;&lt;H3&gt;Minimal Reproduction&lt;/H3&gt;&lt;P&gt;Works:&lt;/P&gt;&lt;PRE&gt;df.writeStream
.format("delta")
.option("checkpointLocation", checkpointPath)
.trigger(Trigger.AvailableNow())
.start(targetPath)&lt;/PRE&gt;&lt;P&gt;Fails (even with an empty&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch):&lt;/P&gt;&lt;PRE&gt;df.writeStream
.foreachBatch { (batchDF: DataFrame, batchId: Long) =&amp;gt;
// no-op
}
.option("checkpointLocation", checkpointPath)
.trigger(Trigger.AvailableNow())
.start()&lt;/PRE&gt;&lt;H3&gt;Observed Behavior&lt;/H3&gt;&lt;UL&gt;&lt;LI&gt;&lt;span class="lia-unicode-emoji" title=":white_heavy_check_mark:"&gt;✅&lt;/span&gt; Kinesis → AvailableNow → Delta sink →&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Success&lt;/STRONG&gt;&lt;/LI&gt;&lt;LI&gt;&lt;span class="lia-unicode-emoji" title=":cross_mark:"&gt;❌&lt;/span&gt; Kinesis → AvailableNow →&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(empty) →&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Fails&lt;/STRONG&gt;&lt;/LI&gt;&lt;LI&gt;&lt;span class="lia-unicode-emoji" title=":cross_mark:"&gt;❌&lt;/span&gt; Kinesis → AvailableNow →&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(full parse/merge/denorm) →&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Fails&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;H3&gt;Failure Symptoms&lt;/H3&gt;&lt;UL&gt;&lt;LI&gt;UDF_ERROR.INTERNAL&lt;/LI&gt;&lt;LI&gt;Underlying gRPC error:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;RST_STREAM&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;PROTOCOL_ERROR&lt;/LI&gt;&lt;LI&gt;Query History and Spark UI provide limited diagnostics for this JAR execution path&lt;/LI&gt;&lt;LI&gt;When execution plans are available, shuffle looks healthy (spark.sql.shuffle.partitions=auto)&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Since the Delta sink succeeds while even an empty&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fails, this doesn't appear to be related to:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Kinesis authentication&lt;/LI&gt;&lt;LI&gt;Unity Catalog service credentials&lt;/LI&gt;&lt;LI&gt;Checkpoint configuration&lt;/LI&gt;&lt;LI&gt;Merge/business logic inside&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch&lt;/LI&gt;&lt;/UL&gt;&lt;H3&gt;What We've Already Ruled Out&lt;/H3&gt;&lt;UL&gt;&lt;LI&gt;Verified the Unity Catalog service credential (Kinesis ingestion succeeds using the Delta sink)&lt;/LI&gt;&lt;LI&gt;Removed&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;persist()/cache()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;after previously hitting&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;NOT_SUPPORTED_WITH_SERVERLESS&lt;/LI&gt;&lt;LI&gt;Removed logging-only&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;.count()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;calls; only use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;limit(1).count()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;where needed&lt;/LI&gt;&lt;LI&gt;Avoid calling&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;SparkSession.builder.getOrCreate()&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;inside&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch; use the existing Spark session&lt;/LI&gt;&lt;LI&gt;Confirmed&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;AvailableNow&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;+ Kinesis&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;initialPosition&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;requirements (latest&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is invalid; testing with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;earliest&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;at_timestamp)&lt;/LI&gt;&lt;/UL&gt;&lt;H3&gt;Questions&lt;/H3&gt;&lt;OL&gt;&lt;LI&gt;&lt;P&gt;Is Scala&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;from a Serverless Jobs JAR officially supported today, or are there known limitations on the Spark Connect execution path used by Serverless?&lt;/P&gt;&lt;/LI&gt;&lt;LI&gt;&lt;P&gt;Is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;UDF_ERROR.INTERNAL&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;wrapping&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;RST_STREAM&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;/&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;PROTOCOL_ERROR&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;a known Spark Connect transport issue with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;foreachBatch, rather than an actual UDF bug?&lt;/P&gt;&lt;/LI&gt;&lt;LI&gt;&lt;P&gt;Before opening a support case, are there any recommended diagnostics we should collect (specific log sections, Spark Connect debug flags, or minimal repro expectations)?&lt;/P&gt;&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;Happy to share a sanitized stack trace in a follow-up if that would be helpful.&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;</description>
      <pubDate>Tue, 04 Aug 2026 13:24:41 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/serverless-scala-jar-foreachbatch-fails-with-rst-stream-protocol/m-p/164827#M55346</guid>
      <dc:creator>adhi_databricks</dc:creator>
      <dc:date>2026-08-04T13:24:41Z</dc:date>
    </item>
    <item>
      <title>Re: Serverless Scala JAR: foreachBatch fails with RST_STREAM PROTOCOL_ERROR</title>
      <link>https://community.databricks.com/t5/data-engineering/serverless-scala-jar-foreachbatch-fails-with-rst-stream-protocol/m-p/164828#M55347</link>
      <description>&lt;P&gt;Hi &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/124788"&gt;@adhi_databricks&lt;/a&gt;&amp;nbsp;!&lt;/P&gt;&lt;P&gt;This is a very specific and subtle architectural edge case when migrating traditional Scala JAR workloads to Databricks Serverless Compute.&lt;/P&gt;&lt;P&gt;The core issue comes down to how Databricks Serverless Jobs execute code via Spark Connect.&lt;/P&gt;&lt;P&gt;Unlike Classic Compute—where your Scala JAR runs directly inside the JVM on the driver node—Serverless Compute executes user code through the Spark Connect architecture (gRPC transport layer).&lt;/P&gt;&lt;P&gt;Here is the breakdown answering your specific questions:&lt;/P&gt;&lt;P&gt;1. Is Scala foreachBatch from a Serverless Jobs JAR officially supported?&lt;BR /&gt;While Scala JAR tasks are supported on Serverless, using arbitrary Scala closures within foreachBatch on Spark Connect / Serverless has known limitations.&lt;/P&gt;&lt;P&gt;In Classic Compute, foreachBatch executes a local JVM closure directly on the driver. In Serverless (Spark Connect), foreachBatch requires serializing and streaming function calls and DataFrame operations back and forth over a gRPC channel between the client context and the remote Spark Connect server.&lt;/P&gt;&lt;P&gt;When complex Scala closure state (or compiler-generated synthetic classes) is passed over this gRPC transport layer, it frequently triggers serialization or protocol mismatches, leading to stream termination.&lt;/P&gt;&lt;P&gt;2. Is UDF_ERROR.INTERNAL wrapping RST_STREAM / PROTOCOL_ERROR a known transport issue?&lt;BR /&gt;Yes. RST_STREAM with PROTOCOL_ERROR is a lower-level HTTP/2 and gRPC transport error.&lt;/P&gt;&lt;P&gt;It indicates that the gRPC channel between the Spark Connect driver client and the Serverless backend was abruptly closed due to an unhandled serialization failure or channel reset during the execution of the closure.&lt;/P&gt;&lt;P&gt;The UDF_ERROR.INTERNAL is simply a high-level Databricks wrapper error catching the failed RPC invocation. It is not an error in your business code logic, which is why even a no-op foreachBatch fails with the exact same error.&lt;/P&gt;&lt;P&gt;3. Workarounds &amp;amp; Alternatives&lt;BR /&gt;Until full parity for native Scala closures over Spark Connect in Serverless is reached, here are the recommended architectural workarounds:&lt;/P&gt;&lt;P&gt;Option A (Recommended for Serverless): Delta Live Tables (DLT) or Declarative Pipelines&lt;BR /&gt;If you are running streaming CDC/Kinesis pipelines to Delta with foreachBatch, moving the pipeline to Delta Live Tables (DLT) / Auto Loader with CDC APIs (apply_changes) completely bypasses foreachBatch and runs natively on Serverless without gRPC closure serialization overhead.&lt;/P&gt;&lt;P&gt;Option B: Run as a Classic Compute Job&lt;BR /&gt;If foreachBatch with custom Scala logic (complex merges/side-effects) is strictly required for your architecture, running this specific streaming task on a single-node or small Auto-scaling Classic Single-User/Shared Cluster remains the most stable path today.&lt;/P&gt;&lt;P&gt;Option C: Refactor to Pure DataFrame / SQL Writes&lt;BR /&gt;If your foreachBatch logic can be expressed purely via native Delta MERGE or DataFrame writes using .writeStream (without custom UDFs or Scala closures inside the batch function), Spark Connect can execute the logical plan natively.&lt;/P&gt;&lt;P&gt;4. Recommended Diagnostics Before Opening a Support Case&lt;BR /&gt;If you proceed with opening a Databricks Support ticket (which is recommended to help the product team track this Spark Connect edge case), gather the following:&lt;/P&gt;&lt;LI-CODE lang="markup"&gt;log4j.logger.org.apache.spark.sql.connect=DEBUG
log4j.logger.io.grpc=DEBUG&lt;/LI-CODE&gt;&lt;UL&gt;&lt;LI&gt;Simplified Standalone Repro: Submit your minimal no-op foreachBatch snippet as a standalone single-class JAR job.&lt;/LI&gt;&lt;LI&gt;Driver Log4j Dump: Export the full driver log showing the exact gRPC stack trace right before RST_STREAM.&lt;/LI&gt;&lt;LI&gt;Hope this helps clarify why the Delta sink works while foreachBatch fails on Serverless!&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;STRONG&gt;If my answer was helpful, please consider marking it as accepted solution!&lt;/STRONG&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 04 Aug 2026 13:49:53 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/serverless-scala-jar-foreachbatch-fails-with-rst-stream-protocol/m-p/164828#M55347</guid>
      <dc:creator>GabFernandes</dc:creator>
      <dc:date>2026-08-04T13:49:53Z</dc:date>
    </item>
    <item>
      <title>Re: Serverless Scala JAR: foreachBatch fails with RST_STREAM PROTOCOL_ERROR</title>
      <link>https://community.databricks.com/t5/data-engineering/serverless-scala-jar-foreachbatch-fails-with-rst-stream-protocol/m-p/164951#M55362</link>
      <description>&lt;P data-pm-slice="1 1 []"&gt;On (1): the docs don't gate Scala &lt;CODE&gt;foreachBatch&lt;/CODE&gt; on serverless. &lt;A href="https://docs.databricks.com/aws/en/dev-tools/databricks-connect/scala/limitations" target="_blank"&gt;Limitations with Databricks Connect for Scala&lt;/A&gt; lists streaming &lt;CODE&gt;foreachBatch&lt;/CODE&gt; as unavailable only on Databricks Runtime 13.3 LTS and below, and &lt;A href="https://docs.databricks.com/aws/en/compute/serverless/limitations" target="_blank"&gt;serverless limitations&lt;/A&gt; names only &lt;CODE&gt;Trigger.ProcessingTime&lt;/CODE&gt; and &lt;CODE&gt;Trigger.Continuous&lt;/CODE&gt; as blocked triggers. Serverless Scala and Java JAR jobs are in Public Preview. I'm reading published docs here, not speaking for support.&lt;/P&gt;
&lt;P&gt;On (2): I can't find any published Databricks doc or KB that names &lt;CODE&gt;RST_STREAM&lt;/CODE&gt; or &lt;CODE&gt;PROTOCOL_ERROR&lt;/CODE&gt;, so I wouldn't put a label on it from out here. One thing worth raising with support: &lt;CODE&gt;[UDF_ERROR](&lt;A href="https://docs.databricks.com/aws/en/error-messages/udf-error-error-class" target="_blank"&gt;https://docs.databricks.com/aws/en/error-messages/udf-error-error-class&lt;/A&gt;)&lt;/CODE&gt; has a dedicated &lt;CODE&gt;ENV_LOST&lt;/CODE&gt; sub-condition for an execution environment that was lost mid-run, and you're getting &lt;CODE&gt;INTERNAL&lt;/CODE&gt; instead. Whether that distinction is meaningful here is a question for whoever picks up the ticket. Your empty no-op result already rules out the merge logic.&lt;/P&gt;
&lt;P&gt;On (3), three things before the case:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;
&lt;P&gt;Make sure your application logs are actually being emitted. On serverless, the SLF4J logging API defaults to a no-op backend and application log output is silently discarded unless you add the &lt;CODE&gt;log4j-slf4j2-impl&lt;/CODE&gt; bridge matching the &lt;CODE&gt;log4j-api&lt;/CODE&gt; version in your environment version (2.20.0 on environment version 5). See &lt;A href="https://docs.databricks.com/aws/en/jobs/jar-create" target="_blank"&gt;Configure logging for serverless compute&lt;/A&gt;. One note on the &lt;CODE&gt;log4j.logger.org.apache.spark.sql.connect=DEBUG&lt;/CODE&gt; suggestion above: Spark logs aren't available on serverless, only client-side application logs, &lt;A href="https://docs.databricks.com/aws/en/spark/conf" target="_blank"&gt;only six Spark properties are settable&lt;/A&gt; and none are log4j-related, and changing the log4j level through &lt;CODE&gt;SparkContext&lt;/CODE&gt; is listed as unavailable. Use the query profile in place of the Spark UI.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Match Scala, JDK, and your Spark API dependency to your &lt;A href="https://docs.databricks.com/aws/en/release-notes/serverless/" target="_blank"&gt;environment version&lt;/A&gt;. You mentioned you're not building against Databricks Connect; &lt;CODE&gt;spark-sql-api&lt;/CODE&gt; is a documented alternative, but Databricks recommends &lt;CODE&gt;databricks-connect&lt;/CODE&gt; marked &lt;CODE&gt;provided&lt;/CODE&gt;, so that's worth ruling out. Don't bundle &lt;CODE&gt;log4j-api&lt;/CODE&gt; or &lt;CODE&gt;log4j-core&lt;/CODE&gt;.&lt;/P&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;P&gt;Isolate &lt;CODE&gt;foreachBatch&lt;/CODE&gt; itself. Swap Kinesis for a small Delta table, &lt;CODE&gt;Trigger.AvailableNow()&lt;/CODE&gt;, empty &lt;CODE&gt;foreachBatch&lt;/CODE&gt;, single-class JAR. Delta is a documented serverless streaming source, so a failure there isolates &lt;CODE&gt;foreachBatch&lt;/CODE&gt; cleanly.&lt;/P&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;If that still fails, it's a clean repro to attach to a support case. On fallback, note that standard access mode also runs on Spark Connect; &lt;A href="https://docs.databricks.com/aws/en/jobs/jar-create" target="_blank"&gt;dedicated compute&lt;/A&gt; is the mode that uses the classic Spark architecture.&lt;/P&gt;</description>
      <pubDate>Wed, 05 Aug 2026 15:05:23 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/serverless-scala-jar-foreachbatch-fails-with-rst-stream-protocol/m-p/164951#M55362</guid>
      <dc:creator>AbhilashNagilla</dc:creator>
      <dc:date>2026-08-05T15:05:23Z</dc:date>
    </item>
  </channel>
</rss>

