Azure Synapse Spark Pool: Executor added mid-execution fails to acquire token, causing job failure

Roman Shamardin 20 Reputation points
2026-06-24T16:29:57.8166667+00:00

Environment Details:

  • Workspace: hasonorthcentralus75c63383c7cd32ae1209
  • Region: North Central US
  • Spark Pool / Livy: SparkV35-987 (Spark 3.5)
  • Application ID: application_1782261914206_0001
  • First Trace ID: 249853a3-7ea9-4e79-95f4-b7e4813aa950

Issue Description:

We are encountering an issue where a long-running Spark application fails after a replacement executor, introduced mid-execution, fails to acquire a storage token.

Error from stderr:

26/06/24 01:29:15 ERROR TokenServiceClient: Token Service returned 'Client Error' (400), with message: {"result":"DependencyError","errorId":"BadRequest","errorMessage":"[Code=400, Target=storage, Message=Entity SparkV35-987 not found, ExceptionDetail=]. TraceId : 249853a3-7ea9-4e79-95f4-b7e4813aa950 | client-request-id : 704bbf75-2d25-4f93-afcc-1e037219cad8. Error Component : LSR"}
com.microsoft.azure.synapse.tokenlibrary.TokenServiceClientResponseStatusException: Token Service returned 'Client Error' (400), with message: {"result":"DependencyError","errorId":"BadRequest","errorMessage":"[Code=400, Target=storage, Message=Entity SparkV35-987 not found, ExceptionDetail=]. TraceId : 249853a3-7ea9-4e79-95f4-b7e4813aa950 | client-request-id : 704bbf75-2d25-4f93-afcc-1e037219cad8. Error Component : LSR"}
	at com.microsoft.azure.synapse.tokenlibrary.TokenServiceClient.invokePostApi(TokenServiceClient.scala:146)
	at com.microsoft.azure.synapse.tokenlibrary.TokenServiceClient.callTokenApi(TokenServiceClient.scala:161)
	at com.microsoft.azure.synapse.tokenlibrary.TokenLibraryInternal.tokenServiceCall(TokenLibraryInternal.scala:120)
	at com.microsoft.azure.synapse.tokenlibrary.TokenLibraryInternal.$anonfun$getAccessToken$4(TokenLibraryInternal.scala:184)
	at com.microsoft.azure.synapse.tokenlibrary.TokenLibraryInternal.checkCacheAndCall$1(TokenLibraryInternal.scala:64)
	at com.microsoft.azure.synapse.tokenlibrary.TokenLibraryInternal.getAccessTokenFromCacheOrCallTokenService(TokenLibraryInternal.scala:74)
	at com.microsoft.azure.synapse.tokenlibrary.TokenLibraryInternal.getAccessToken(TokenLibraryInternal.scala:184)
	at com.microsoft.azure.synapse.tokenlibrary.TokenLibrary$.getAccessToken(TokenLibrary.scala:79)
	at com.microsoft.azure.synapse.tokenlibrary.TokenLibrary$.getAccessToken(TokenLibrary.scala:87)
	at com.microsoft.vegas.TokenLibraryUtils$.$anonfun$getAccessToken$1(TokenLibraryUtils.scala:31)
	at scala.util.Try$.apply(Try.scala:213)
	at com.microsoft.vegas.TokenLibraryUtils$.getAccessToken(TokenLibraryUtils.scala:31)
	at com.microsoft.vegas.TokenLibraryUtils$.fsAccessToken(TokenLibraryUtils.scala:42)
	at com.microsoft.vegas.TokenLibraryUtils$.getfsAccessToken(TokenLibraryUtils.scala:49)
	at org.apache.spark.VStreamHttpUtils.submitHttpPostToVegas(VStreamHttpUtils.scala:577)
	at org.apache.spark.sql.execution.datasources.csv.VegasCSVFileFormat.$anonfun$buildReader$2(VegasCSVFileFormat.scala:274)
	at org.apache.spark.sql.execution.datasources.FileFormat$$anon$1.apply(FileFormat.scala:155)
	at org.apache.spark.sql.execution.datasources.FileFormat$$anon$1.apply(FileFormat.scala:140)
	at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.org$apache$spark$sql$execution$datasources$FileScanRDD$$anon$$readCurrentFile(FileScanRDD.scala:263)
	at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.nextIterator(FileScanRDD.scala:328)
	at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.hasNext(FileScanRDD.scala:173)
	at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
	at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage2.processNext(Unknown Source)
	at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
	at org.apache.spark.sql.execution.WholeStageCodegenEvaluatorFactory$WholeStageCodegenPartitionEvaluator$$anon$1.hasNext(WholeStageCodegenEvaluatorFactory.scala:43)
	at scala.collection.Iterator$$anon$10.hasNext(Iterator.scala:460)
	at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:155)
	at org.apache.spark.shuffle.ShuffleWriteProcessor.write(ShuffleWriteProcessor.scala:98)
	at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:104)
	at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:54)
	at org.apache.spark.TaskContext.runTaskWithListeners(TaskContext.scala:166)
	at org.apache.spark.scheduler.Task.run(Task.scala:141)
	at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$4(Executor.scala:636)
	at org.apache.spark.util.SparkErrorUtils.tryWithSafeFinally(SparkErrorUtils.scala:64)
	at org.apache.spark.util.SparkErrorUtils.tryWithSafeFinally$(SparkErrorUtils.scala:61)
	at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:94)
	at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:639)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)

Request: Could you please assist in identifying why the newly added/replacement executors in this workspace and pool are unable to retrieve the storage tokens mid-execution?

Azure Synapse Analytics
Azure Synapse Analytics

An Azure analytics service that brings together data integration, enterprise data warehousing, and big data analytics. Previously known as Azure SQL Data Warehouse.


Answer accepted by question author

Manoj Kumar Boyini 18,595 Reputation points Microsoft External Staff Moderator
2026-06-24T19:32:52.45+00:00

Hi @Roman Shamardin

The issue was caused by memory pressure on the driver/head node. During execution, the available memory on the node dropped to a critically low level, resulting in high CPU load and resource contention.

Since the Livy service is co-located on the driver/head node, it became unresponsive under the resource pressure and stopped responding to control-plane requests. This led to the Spark session being terminated, which subsequently triggered errors such as UNABLE_TO_REACH_LIVY, Invalid JobSessionToken, Entity SparkV35-987 not found, storage token acquisition failures, and ultimately application failure.

These errors are downstream symptoms of the head-node resource exhaustion rather than issues with storage access, identity configuration, or authentication.

Recommendation

We recommend increasing the Spark pool node size to provide additional memory capacity for the driver/head node. Additionally, review the workload for driver-intensive operations such as large collect() operations, excessive caching/persisting, large broadcast variables, or long-running workloads with many stages, as these can significantly increase memory consumption on the driver.

This was a driver/head-node resource exhaustion issue rather than a storage, identity, or authentication issue. For workloads that run for extended periods or process large volumes of data, consider using a larger Spark pool SKU to ensure sufficient resources are available for both the Spark driver and Livy service.

Please let us know if you have any questions.

Was this answer helpful?

1 person found this answer helpful.
0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Jerald Felix 16,420 Reputation points Volunteer Moderator
    2026-06-24T16:48:53.8+00:00

    Hello Roman Shamardin,

    Greetings! Thanks for raising this question in Q&A forum.

    You have provided an excellent and detailed error report. The key signal is in this part of the error message:

    Message=Entity SparkV35-987 not found
    Error Component: LSR
    

    The LSR (Linked Service Resolver) component is the internal Synapse service that resolves pool identity context when executors request storage tokens. The error Entity SparkV35-987 not found means that when the replacement executor was provisioned mid-execution and attempted to call the Token Service to acquire a storage access token, the LSR could not find the pool's registration entry in its backend lookup. This is a race condition between the executor provisioning timeline and the LSR's pool entity registration.

    Here is what is happening and what you can do.

    Root cause explanation:

    When a long-running Spark job triggers executor replacement (due to node failure, spot eviction, or autoscale-triggered node replacement), the new executor node needs to register itself with the Synapse Token Service (which uses LSR internally) to prove it is an authorized member of pool SparkV35-987 before it can request storage tokens. In some cases, particularly for long-running jobs where the initial pool session has been running for many hours, there is a timing window where the replacement executor comes online before its pool entity context has been fully propagated or refreshed in LSR. The Entity SparkV35-987 not found message is the LSR saying it cannot find the pool registration entry to validate the token request against.

    This is a known scenario that Microsoft is aware of for Spark 3.x pools with autoscale or dynamic executor allocation enabled for long-running jobs.

    Step 1: Open an Azure Support ticket immediately with your trace IDs.

    This specific class of error (Entity SparkPool not found from the LSR) requires a backend investigation against the LSR service logs for your workspace. The trace IDs you have already captured are exactly what the support team needs. Please open a support ticket immediately and include:

    • Workspace name: hasonorthcentralus75c63383c7cd32ae1209
    • Spark Pool name: SparkV35-987
    • Application ID: application_1782261914206_0001
    • First Trace ID: 249853a3-7ea9-4e79-95f4-b7e4813aa950
    • Client Request ID from the error: 704bbf75-2d25-4f93-afcc-1e037219cad8
    • Error Component: LSR
    • State explicitly: "Replacement executor added mid-execution cannot acquire Token Service registration. Entity SparkV35-987 not found in LSR. Requesting investigation of LSR registration state for this pool."

    Go to Azure portal > Help + Support > New support request > Issue type: Technical > Service: Azure Synapse Analytics.

    Step 2: As a short-term mitigation, reduce reliance on executor replacement by adjusting your autoscale and dynamic allocation settings.

    The failure happens because a replacement executor is added mid-execution. You can reduce how aggressively new executors are brought in by setting more conservative dynamic allocation bounds in your Spark configuration. Add this to your Spark job or notebook configuration:

    %%configure -f
    {
      "conf": {
        "spark.dynamicAllocation.enabled": "true",
        "spark.dynamicAllocation.minExecutors": "2",
        "spark.dynamicAllocation.maxExecutors": "10",
        "spark.dynamicAllocation.executorIdleTimeout": "300s",
        "spark.dynamicAllocation.cachedExecutorIdleTimeout": "600s",
        "spark.task.maxFailures": "8"
      }
    }
    

    Increasing spark.task.maxFailures above the default of 4 gives failing tasks more retries during which the executor registration may complete, which can allow the job to recover without full failure. Setting a longer executorIdleTimeout reduces the frequency of executor churn that triggers replacement.

    Step 3: Consider switching storage access to use the workspace Managed Identity directly instead of the LSR token path.

    The stack trace shows the error is occurring in VStreamHttpUtils calling through TokenLibraryUtils.getfsAccessToken, which routes through LSR. For long-running jobs that read from ADLS Gen2 primary storage linked to the workspace, you can configure Spark to use the workspace Managed Identity directly with OAuth, bypassing the Synapse Token Service entirely:

    spark.conf.set(
        "fs.azure.account.auth.type.<your-storage-account>.dfs.core.windows.net",
        "OAuth"
    )
    spark.conf.set(
        "fs.azure.account.oauth.provider.type.<your-storage-account>.dfs.core.windows.net",
        "org.apache.hadoop.fs.azurebfs.oauth2.MsiTokenProvider"
    )
    spark.conf.set(
        "fs.azure.account.oauth2.msi.endpoint.<your-storage-account>.dfs.core.windows.net",
        "http://169.254.169.254/oauth2/token"
    )
    

    This uses IMDS (Instance Metadata Service) to get a Managed Identity token directly on each executor node, which does not depend on the LSR pool entity registration and therefore will not be affected by the mid-execution replacement timing issue.

    Step 4: Verify your Spark Pool autoscale configuration is correctly specified.

    Ensure that your pool's autoscale min and max node counts are explicitly set and that dynamic executor allocation has explicit min and max executor values configured at the pool level. In scenarios where the Dynamic Allocation option is enabled in a Synapse Spark Pool, the platform reserves the number of executors based on the maximum limit specified by the user for any Spark application submitted. If these are not set correctly, the platform may make suboptimal scaling decisions that increase executor replacement frequency.

    You can verify or update via Azure CLI:

    az synapse spark pool update \
      --name SparkV35-987 \
      --workspace-name hasonorthcentralus75c63383c7cd32ae1209 \
      --resource-group <your-resource-group> \
      --enable-dynamic-exec \
      --min-executors 3 \
      --max-executors 20
    
    

    If this answer helps you kindly accept the answer which will help others who have similar questions.

    Best Regards,

    Jerald Felix.

    Was this answer helpful?


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.