Forum Discussion
Fabric Pipeline fails to access user data function
Hello,
I'm facing an issue with fabric pipeline access user data function. I'd appreciate your inputs on this issue. Thanks a lot
Context:
- I have a user data function called: config_utils (receive a workspace_id and return a string)
- In a notebook, Im invoking that udf with this code:
config_utils = notebookutils.udf.getFunctions('config_utils', ws_id)- It works without any issue under my personal identity account (I have admin access in the workspace)
- However, in a pipeline which runs under a service principle which i added as an admin in the workspace as well
Problem: Its throwing this error even if the service principle has admin permission, its the owner of the user data function, its the owner of the pipeline and the udf grants the service principle read/write/execute access
---------------------------------------------------------------------------
Py4JJavaError Traceback (most recent call last)
Cell In[21], line 1
----> 1 config_utils = notebookutils.udf.getFunctions('config_utils', ws_id)
File ~/cluster-env/trident_env/lib/python3.11/site-packages/notebookutils/udf.py:21, in getFunctions(udf, workspaceId)
9 def getFunctions(udf: str, workspaceId: str = "") -> UDF:
10 """
11 Get the User data functions (UDF).
12 :param udf: The UDF artifact id or name.
(...)
19 myFunctions.multiply(1, 2, 3) # call function multiply
20 """
---> 21 return _udf.getFunctions(udf, workspaceId)
File ~/cluster-env/trident_env/lib/python3.11/site-packages/notebookutils/mssparkutils/handlers/udfHandler.py:109, in UdfHandler.getFunctions(self, artifact, workspace_id)
107 if not workspace_id:
108 workspace_id = self.getCurrentWorkspaceId()
--> 109 metadata = self.jvm.notebookutils.udf.getMetadataStr(artifact, workspace_id)
110 metadata = json.loads(metadata)
111 name = metadata.get("displayName", "")
File ~/cluster-env/trident_env/lib/python3.11/site-packages/py4j/java_gateway.py:1322, in JavaMember.__call__(self, *args)
1316 command = proto.CALL_COMMAND_NAME +\
1317 self.command_header +\
1318 args_command +\
1319 proto.END_COMMAND_PART
1321 answer = self.gateway_client.send_command(command)
-> 1322 return_value = get_return_value(
1323 answer, self.gateway_client, self.target_id, self.name)
1325 for temp_arg in temp_args:
1326 if hasattr(temp_arg, "_detach"):
File /opt/spark/python/lib/pyspark.zip/pyspark/errors/exceptions/captured.py:179, in capture_sql_exception.<locals>.deco(*a, **kw)
177 def deco(*a: Any, **kw: Any) -> Any:
178 try:
--> 179 return f(*a, **kw)
180 except Py4JJavaError as e:
181 converted = convert_exception(e.java_exception)
File ~/cluster-env/trident_env/lib/python3.11/site-packages/py4j/protocol.py:326, in get_return_value(answer, gateway_client, target_id, name)
324 value = OUTPUT_CONVERTER[type](answer[2:], gateway_client)
325 if answer[1] == REFERENCE_TYPE:
--> 326 raise Py4JJavaError(
327 "An error occurred while calling {0}{1}{2}.\n".
328 format(target_id, ".", name), value)
329 else:
330 raise Py4JError(
331 "An error occurred while calling {0}{1}{2}. Trace:\n{3}\n".
332 format(target_id, ".", name, value))
Py4JJavaError: An error occurred while calling z:notebookutils.udf.getMetadataStr.
: java.lang.Exception: Request to https://api.fabric.microsoft.com/metadata/artifacts/3f4fe48c-482d-444c-bd9e-ab22c1d8eddd failed with status code: 401, response:, response headers: Array(Content-Length: 0, Strict-Transport-Security: max-age=31536000; includeSubDomains, X-Frame-Options: deny, X-Content-Type-Options: nosniff, Access-Control-Expose-Headers: RequestId, RequestId: e0a1e0ff-8fed-45c7-bdbd-374964913167, Date: Thu, 28 May 2026 07:32:31 GMT)
at com.microsoft.spark.notebook.workflow.client.FabricClient.getEntity(FabricClient.scala:126)
at com.microsoft.spark.notebook.workflow.client.BaseRestClient.get(BaseRestClient.scala:120)
at com.microsoft.spark.notebook.msutils.impl.fabric.MSArtifactUtilsImpl.getMetadata(MSArtifactUtilsImpl.scala:276)
at com.microsoft.spark.notebook.msutils.impl.fabric.UdfUtilsImpl$.getMetadata(UdfUtilsImpl.scala:238)
at notebookutils.udf$.$anonfun$getMetadataStr$1(udf.scala:79)
at com.microsoft.spark.notebook.common.trident.CertifiedTelemetryUtils$.withTelemetry(CertifiedTelemetryUtils.scala:98)
at notebookutils.udf$.getMetadataStr(udf.scala:77)
at notebookutils.udf.getMetadataStr(udf.scala)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:374)
at py4j.Gateway.invoke(Gateway.java:282)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.GatewayConnection.run(GatewayConnection.java:238)
at java.base/java.lang.Thread.run(Thread.java:829)
Hi dungp,
Based on the error, this does not look like a classic workspace permission issue.
Your Service Principal may be Admin on the workspace and may even own the pipeline/UDF item, but the call is failing when notebookutils.udf.getFunctions() tries to retrieve the UDF metadata through the Fabric metadata API.
According to the current User Data Functions limitations, accessing Fabric items or data sources using a Service Principal is not currently supported in some UDF scenarios. So the 401 is likely caused by the execution identity/context rather than by missing workspace permissions.
A few things I would check :
1. Test the same pipeline/notebook with an interactive user identity.
2. Confirm whether the issue only happens when the pipeline runs under the Service Principal.
3. If yes, this is probably a current product limitation rather than a misconfiguration.
4. As a workaround, you may need to run the notebook/pipeline under a user identity, or move this logic outside the UDF call until SPN support is fully available for this execution path.Docs:
- NotebookUtils UDF getFunctions : https://learn.microsoft.com/en-us/fabric/data-engineering/notebookutils/notebookutils-user-data-function
- User Data Functions limitations : https://learn.microsoft.com/en-us/fabric/data-engineering/user-data-functions/user-data-functions-service-limitsHope this helps clarify the root cause.
If this helped, please consider marking it as a solution so others can find it more easily.Thanks a lot for your answer Tamanchu. The pipeline runs without issue under my identity, so i believe the issue only happens when it runs under the Service Principle. I've reached out to Microsoft for the confirmation, if thats the issue then i will mark your answer as solution!
Regarding working around, i reverted changes back to using the %run maggic command with notebooks to load the logics instead of using UDF. I think using UDF is a proper and standard way to handle shared codes, but it seems we need to wait a bit before we can fully leverage this feature.
Thanks again!
4 Replies
- Tamanchu
Super User
Hi dungp,
Based on the error, this does not look like a classic workspace permission issue.
Your Service Principal may be Admin on the workspace and may even own the pipeline/UDF item, but the call is failing when notebookutils.udf.getFunctions() tries to retrieve the UDF metadata through the Fabric metadata API.
According to the current User Data Functions limitations, accessing Fabric items or data sources using a Service Principal is not currently supported in some UDF scenarios. So the 401 is likely caused by the execution identity/context rather than by missing workspace permissions.
A few things I would check :
1. Test the same pipeline/notebook with an interactive user identity.
2. Confirm whether the issue only happens when the pipeline runs under the Service Principal.
3. If yes, this is probably a current product limitation rather than a misconfiguration.
4. As a workaround, you may need to run the notebook/pipeline under a user identity, or move this logic outside the UDF call until SPN support is fully available for this execution path.Docs:
- NotebookUtils UDF getFunctions : https://learn.microsoft.com/en-us/fabric/data-engineering/notebookutils/notebookutils-user-data-function
- User Data Functions limitations : https://learn.microsoft.com/en-us/fabric/data-engineering/user-data-functions/user-data-functions-service-limitsHope this helps clarify the root cause.
If this helped, please consider marking it as a solution so others can find it more easily.- dungpRegular Visitor
Thanks a lot for your answer Tamanchu. The pipeline runs without issue under my identity, so i believe the issue only happens when it runs under the Service Principle. I've reached out to Microsoft for the confirmation, if thats the issue then i will mark your answer as solution!
Regarding working around, i reverted changes back to using the %run maggic command with notebooks to load the logics instead of using UDF. I think using UDF is a proper and standard way to handle shared codes, but it seems we need to wait a bit before we can fully leverage this feature.
Thanks again!