Apache Spark job fails with EncryptionOperationNotPossibleException in Jasypt UDF

Enhance the UDF with input validation and exception handling.

Written by joel.robin

Last published at: August 28th, 2025

Problem

You are executing an Apache Spark job that performs encryption and decryption operations using a user-defined function (UDF). However, the job intermittently fails with the following error. 

org.apache.spark.SparkException: [FAILED_EXECUTE_UDF] User defined function (`<function-name> (UDFRegistration$$Lambda$9666/490708012)`: (string) => string) failed due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException. SQLSTATE: 39000

 

When reviewing the stack trace, you note the Caused by: line, which identifies the root exception raised by the Jasypt library. 

org.apache.spark.SparkException: [FAILED_EXECUTE_UDF] User defined function (`UDJF_DecryptionUtil (UDFRegistration$$Lambda$9666/490708012)`: (string) => string) failed due to: org.jasypt.exceptions.EncryptionOperationNotPossibleException. SQLSTATE: 39000
at org.apache.spark.sql.errors.QueryExecutionErrors$.failedExecuteUserDefinedFunctionError(QueryExecutionErrors.scala:243)
at org.apache.spark.sql.errors.QueryExecutionErrors.failedExecuteUserDefinedFunctionError(QueryExecutionErrors.scala)
at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIteratorForCodegenStage1.processNext(Unknown Source)
at at com.databricks.spark.util.ExecutorFrameProfiler$.record(ExecutorFrameProfiler.scala:110)
at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:928)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:750)
Caused by: org.jasypt.exceptions.EncryptionOperationNotPossibleException
at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.decrypt(StandardPBEByteEncryptor.java:1169)
at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:738)
at org.jasypt.encryption.pbe.PooledPBEStringEncryptor.decrypt(PooledPBEStringEncryptor.java:511)
at com.DecryptionUtil.hello(DecryptionUtil.java:50)
at com.DecryptionUtil.call(DecryptionUtil.java:58)
at com.DecryptionUtil.call(DecryptionUtil.java:1)
at org.apache.spark.sql.UDFRegistration.$anonfun$register$352(UDFRegistration.scala:784)
... 39 more

 

Cause

You have malformed, corrupted, or incompatible records in the input dataset that are passed to your decryption UDF. These entries can occur if:

  • The data was encrypted using an incorrect or mismatched encryption key.
  • An incompatible encryption algorithm was used for some records.
  • Certain records were never encrypted but are still being processed by the decryption logic.
  • Null, empty, or unexpected string values are present, which are not handled explicitly by the UDF.

 

When your UDF relies on the Jasypt library to perform decryption, the input must conform to expected encryption standards or formats. If the input does not conform, Jasypt library throws the EncryptionOperationNotPossibleException

 

Further, if your UDF implementation does not include defensive programming constructs such as input validation, try-catch blocks, or fallback logic, this exception remains unhandled, causing the Spark task to fail entirely.

 

Solution

Make your job resilient and prevent task-level failures due to isolated data issues with the following implementation enhancements. 

 

  1. Before attempting decryption, validate the input string. Ensure it is not null or empty, and conforms to expected cipher format (for example, Base64-encoded).

     
  2. Wrap the decryption logic in a try-catch block. In case of failure, log the offending input for further analysis and return a placeholder value (for example, null or an error flag), or skip the record based on business requirements.

     
  3. Analyze the source data to identify any inconsistencies such as:

    • Mixed encryption standards across records.
    • Partial or corrupted ciphertexts.
    • Records processed or written by upstream systems using incompatible keys or configurations.

       
  4. Incorporate logging mechanisms within the UDF to capture stack traces or error messages for failed decryptions. This aids in debugging and long-term data quality improvements.