Skip to main content
Question

Intermittent 403 issue for timeseries

  • April 9, 2026
  • 5 replies
  • 17 views

Hello,

I am running a function ‘dq_validate_model_integrity’ and ‘dq_validate_broken_references’ which give a 403 unauthorized error for a timeseries intermittently. There has been no change in access or data yet its failing sometimes with a 403 error.

Could you please let us know why this issue is coming up frequently?

PS: I have attached the screenshots of the passed and failed statuses of both functions with the timestamp as well as the logs of both failed functions.

 

Do let me know if there’s any more information required from my end.

 

Thanks alot :)

5 replies

cc: ​@Snehal Jagtap ​@Sonali Vishal Patil  ​@Shivani Mishra 


Michael Bennett
Practitioner
Forum|alt.badge.img

Hi ​@Nikita Chandrashekhar Sawant  Could you please clean your handler.py of any sensitive data and post here? Each log is pointing to the handler.py at different lines. 

04-09T05:35+05:30 : Traceback (most recent call last):
2026-04-09T05:35+05:30 : File "/home/site/wwwroot/function/_cognite_function_entry_point.py", line 665, in run_handle
2026-04-09T05:35+05:30 : result = handle(**function_argument_values)
2026-04-09T05:35+05:30 : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-04-09T05:35+05:30 : File "/home/site/wwwroot/function/handler.py", line 63, in handle
2026-04-09T05:35+05:30 : total_checked, broken_count = validate_broken_references(client,fetched_views,input_json)

 

 

2026-04-09T05:36+05:30 : Traceback (most recent call last):
2026-04-09T05:36+05:30 : File "/home/site/wwwroot/function/_cognite_function_entry_point.py", line 665, in run_handle
2026-04-09T05:36+05:30 : result = handle(**function_argument_values)
2026-04-09T05:36+05:30 : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-04-09T05:36+05:30 : File "/home/site/wwwroot/function/handler.py", line 31, in handle
2026-04-09T05:36+05:30 : report, total_checked, broken_count = validate_broken_references(
2026-04-09T05:36+05:30 : ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Regards,

Michael Bennett

Cognite Academy Engineer


@Michael Bennett  Sure! I’ve attached the handler.py of both functions ‘dq_validate_model_integrity’ and ‘dq_validate_broken_references’. 

 

Just a heads-up: Handler.py is simply the entry point for the function. From the logs, it looks like the error is actually coming from the following calls to cognite sdk "client.time_series.retrieve_multiple(external_ids=list(timeseries_targets))" and "client.time_series.retrieve_multiple(external_ids=external_ids)" for the "dq_validate_broken_references" function and "dq_validate_model_integrity" functions respectively. 

 

Do let me know if any more information is needed :)

 

cc: ​@Snehal Jagtap ​@Sonali Vishal Patil ​@Shivani Mishra 
 


Michael Bennett
Practitioner
Forum|alt.badge.img

Hi ​@Nikita Chandrashekhar Sawant  I’ll break these down separately, so let’s talk about val_broken_ref first.

 

I’d suggest modifying the validate_references.py to handle the 403 errors, so the function doesn’t crash when we encounter a TS the service manager doesn’t have access to. I placed an empty or partial list in the fetch existing timeseries function to handle it.
 

from cognite.client.exceptions import CogniteAPIError

def fetch_existing_timeseries(client, timeseries_targets):
try:
# Attempt to retrieve the time series
ts_list = client.time_series.retrieve_multiple(
external_ids=list(timeseries_targets),
ignore_unknown_ids=True
)
return ts_list
except CogniteAPIError as e:
if e.code == 403:
# Log the error but don't crash.
# You might want to treat these as "Broken" or "Inaccessible"
print(f"Access Denied (403) for some time series in project {e.project}")
# Depending on your logic, return an empty list or partial list
return []
raise e # Re-raise if it's a different error (e.g., 500 or 401)

 

 

 

For you to get the most out of the function and the best data returned, I would suggest the following capabilities for the service manager that is executing the function:

 

 

 

resource capability scope REASON
TIMESERIES READ ALL OR SPECIFIC DATA SET To verify the existence of the TS targets.
DATA SET READ ALL Often required to resolve metadata for the items being checked.
DATAMODEL INSTANCES READ ALL Fetching views and PDM model version

 

 

Regards,

Michael Bennett

Academy Engineer


Michael Bennett
Practitioner
Forum|alt.badge.img

Hi ​@Nikita Chandrashekhar Sawant. Now for the validate model integrity:

Similar to the broken references function, you’re failing on a timeseries that you don’t have access to.

 

I’d suggest a workaround in validate_refeences.py to handle the 403 errors so that Rule #5 can still calculate a score and the function can complete. The retrieve multiple is wrapped in a try-except block so the function won’t fail on a 403. 

 

# Inside validate_references.py
from cognite.client.exceptions import CogniteAPIError

def fetch_existing_timeseries(client, external_ids):
try:
return client.time_series.retrieve_multiple(external_ids=external_ids, ignore_unknown_ids=True)
except CogniteAPIError as e:
if e.code == 403:
# Print a clear warning in the Cognite Function logs
print(f"PERMISSION ERROR: The function cannot access {len(external_ids)} time series.")
print(f"Check ACLs for the Service Principal in project: {e.project}")
# Returning an empty list prevents the crash and treats these as 'not found'
return []
raise e

We’re still receiving 403s on a TS that your service manager does not have access to, so we should address that as well. Here’s the capabilities suggested for the service manager.

 

resource capability scope reason
Timeseries read Avocent or the source of the TS Need the capability to read the TS
Datamodel read DQ space

we are reading the PDM and DQ  

Datamodel Instance write  DQ_DATA_SPACE Writing to DQ Space

 

 

***Unrelated but please verify***

Please take a look at your input_json to verify the integrity of your data. The fetch_views_for_category will be broken if the data model space and DM version are not correct.