Forum Discussion

smeetsh's avatar
smeetsh
Icon for Continued Contributor rankContinued Contributor
1 month ago
Solved

SQL Endpoint lakehouse: Intermittent error in the Refresh SQL analytics endpoint activity

Hi All,

since Monday we are having intermittent issues with the Refresh SQL analytics endpoint in our pipelines in fabric.  We run multiple pipelines on an F8 sku, which Monday was about 60% used and today about 70% used, so enough capacity.

I do see there is a Fabric service degradation, but the description doesn't match the issue (though I have seen often enough that that doesn't have to mean anything)

The error is: 
"Error calling the endpoint 'https://api.fabric.microsoft.com'. Response status code: 'ClientSideException HttpStatusCode : 408, HttpStatusString: RequestTimeout'. More details: Exception message: 'NA - Unknown [ClientSideException] A task was canceled.'.

Request didn't reach the server from the client. This could happen because of an underlying issue such as network connectivity, a DNS failure, a server certificate validation or a timeout. Url endpoint request timed out. Please make sure the endpoint response is within 1 minute and retry."



I have implemented a retry on a few of our pipelines but of course as luck would have it the last set of runs was fine and fast. We were very happy with the GA release of the Refresh SQL analytics endpoint activity, since we could get rid of the forced waits we had to build into our pipelines, but this is not much of an improvement if this keeps happening.

Does anyone have any idea? Just a glitch, or (as co-pilot said) "known issue with the acknowledgement of the refresh not reaching the activity.

Cheers

Hans

  • Thank you for all the responses, going down the full api/notebook route is too much of an overhead for us at the moment. It would require us to set up a service principal,  api keys etc, which we (don't) have (yet) (very small team :-) )

    We do know from experience that a 5-minute wait in our pipeline, though ugly, solved the issue. Endpoints would have synched by then. 

    (The only time that did not work flawless was on 1 pipeline that ran at 130 am in the morning, when the lakehouse was well deep asleep. I solved that by running a dummy script against the endpoint...select top (1) from etc etc.

    With that in mind I would think that (in our situation) "on completion" would be safe?

    Cheers

    Hans

6 Replies

  • v-sathmakuri's avatar
    v-sathmakuri
    Icon for Community Support rankCommunity Support

    Hi smeetsh​ ,

    Thank you for reaching out to fabric community.

    • This is most likely a transient Fabric API timeout not an F8 capacity issue.
    • Add a Retry policy with a delay to the Refresh SQL analytics endpoint activity.
    • Ensure the activity runs after all Lakehouse write / ingestion operations are completed to avoid concurrent update / locking issues.
    • Microsoft's current documentation specifically states that the activity can intermittently fail when other processes are actively updating the underlying Lakehouse, because the SQL analytics endpoint needs to acquire internal locks. However, the exact 408 Request Timeout / A task was canceled error in your example is not explicitly documented as the known issue.

    Refresh SQL analytics endpoint activity - Microsoft Fabric | Microsoft Learn

    Thanks!!

     

  • ShivekMaharaj's avatar
    ShivekMaharaj
    Icon for Community Champion rankCommunity Champion

    Hi smeetsh​,

    I think there are two possibilities worth separating here.

    Microsoft now explicitly documents that the Refresh SQL analytics endpoint activity can fail intermittently when another process is actively writing to or updating the underlying Lakehouse.

    The reason is that the SQL analytics endpoint needs to acquire internal locks during the metadata refresh. If ingestion, a notebook, maintenance operation, or another write is holding the relevant data/metadata structures, the refresh can time out.

    Microsoft documents that behavior in the Refresh SQL analytics endpoint activity guidance.

    So I would first make sure your pipeline follows this pattern:

    all ingestion / notebook / maintenance activity
    -> wait until those writes are fully complete
    -> one Refresh SQL analytics endpoint activity at the end

    rather than refreshing multiple times while Lakehouse updates are still happening.

    However, I would not say the lock scenario is definitely the explanation for your exact error.

    Your message is:

    HTTP 408 RequestTimeout
    “A task was canceled”

    and you are also seeing intermittent success while there is a Fabric service degradation.

    That could still be a transient Fabric API/service-side timeout rather than purely Lakehouse lock contention.

    A couple of things I would check:

    1. Confirm that no notebook, Copy activity, maintenance task, or other writer is still touching the Lakehouse when the refresh starts.
    2. Keep the retry, but use a delay/backoff rather than retrying immediately.
    3. Check whether failures correlate with periods of concurrent Lakehouse writes.
    4. Compare the failed timestamps with Fabric Service Health.
    5. If the same 408 occurs when the Lakehouse has been completely idle for several minutes, I would capture the pipeline run ID, workspace ID, endpoint ID, timestamp and correlation/request details and raise a support case.


    One other consideration is whether you need the forced refresh on every run.

    Microsoft’s SQL analytics endpoint metadata sync documentation says Fabric already maintains the endpoint through a background metadata-sync process.

    Under normal operating conditions, Microsoft says the lag between the Lakehouse and SQL analytics endpoint is generally less than one minute, although it can range from seconds to minutes.

    So if your downstream workload can tolerate that delay, you may not need to force a refresh after every pipeline execution.

    If deterministic freshness is required, then I would keep the activity, but run it once at the very end and retain the retry/backoff logic.

    So my view would be:

    concurrent Lakehouse writes
    -> documented intermittent refresh failures
    
    idle Lakehouse + repeated HTTP 408 failures
    -> more likely worth investigating as a Fabric service/API issue

    Given that you are already seeing a service degradation, I would not rule out the second case yet.

    AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.

  • smeetsh's avatar
    smeetsh
    Icon for Continued Contributor rankContinued Contributor

    Scheduling the refresh activity to only run after the write to lakehouse is sadly not an option. We have multiple pipelines some relying on each other , some scheduled specifically to meet a Business need.  I fear a retry could potentially only make it worse.

    Another idea i had was to have the next step in the pipeline start on both success and on fail. Would that work this way? The reason is: The error will be thrown after about 12 minutes, which means that specific dataset in the sql-endpoint will have refreshed anyway?

    I mean something like this:

     

    • ShivekMaharaj's avatar
      ShivekMaharaj
      Icon for Community Champion rankCommunity Champion

      Hi smeetsh​,

      Yes, it is possible that some tables have already synchronized before the activity ultimately fails.

      The Refresh SQL analytics endpoint operation works against unsynchronized Lakehouse metadata/tables, so an overall timeout or failure does not necessarily mean that every table remained unchanged.

      Fabric also maintains a background metadata synchronization process independently of this activity.

      Microsoft documents the activity behavior in the Refresh SQL analytics endpoint guidance.

      Because of that, I would be careful with this pattern:

      Refresh SQL endpoint
      -> on success OR failure
      -> continue with downstream processing

      It is technically possible to configure the pipeline that way, but a failure branch means you no longer have a deterministic guarantee that the SQL endpoint reflects all Lakehouse changes.

      If the next activity can tolerate slightly stale metadata, then continuing on failure may be acceptable.

      If the downstream step requires the SQL endpoint to be fully current, I would instead use:

      Refresh SQL endpoint
      -> retry with delay
      -> continue only on success

      and handle the final failure separately.

      Microsoft’s pipeline activities support configurable retries and retry intervals, which is useful for these transient timeout/locking scenarios.

      There is also one useful distinction:

      Success
      -> unsynchronized data was synchronized successfully
      
      NotRun
      -> there was nothing new to synchronize
      
      Failure
      -> something went wrong, and you should not assume the endpoint is fully synchronized

      So I would not use the failure path as an equivalent success path unless your downstream logic explicitly tolerates eventual consistency.

      Given your ~12 minute timeout pattern, I would prefer a delayed retry first, and only continue after failure if the business process can safely work with potentially stale SQL endpoint metadata.

      AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.

  • jubinsoni's avatar
    jubinsoni
    Icon for Memorable Member rankMemorable Member

    Hi smeetsh​,

    On your continue-on-failure idea, one option that gives you a deterministic answer instead of guessing is to call the refresh API directly rather than through the pipeline activity, because the API returns a status per table.

    POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}
         /sqlEndpoints/{sqlEndpointId}/refreshMetadata

    Two optional body parameters in the Refresh SQL Endpoint Metadata API help with your exact situation:

    tables   -> refresh only the tables this pipeline wrote
                (up to 25 per call)
    timeout  -> defaults to 15 minutes, can be raised

    The response lists each table with a status (Success, Failure or NotRun) and its lastSuccessfulSyncDateTime.

    A minimal notebook version, which you can call from the pipeline in place of the activity:

    import time, requests
    
    ws_id, ep_id = "<workspaceId>", "<sqlEndpointId>"
    token = notebookutils.credentials.getToken("pbi")
    h = {"Authorization": f"Bearer {token}"}
    url = (f"https://api.fabric.microsoft.com/v1/workspaces/{ws_id}"
           f"/sqlEndpoints/{ep_id}/refreshMetadata")
    
    body = {
        "tables": [{"schema": "dbo",
                    "tableNames": ["trev_checklist_data"]}],
        "timeout": {"timeUnit": "Minutes", "value": 30},
    }
    
    r = requests.post(url, headers=h, json=body)
    if r.status_code == 202:  # long-running operation
        op_url = r.headers["Location"]
        while True:
            time.sleep(int(r.headers.get("Retry-After", 15)))
            r = requests.get(op_url, headers=h)
            if r.json().get("status") in ("Succeeded", "Failed"):
                break
        r = requests.get(op_url + "/result", headers=h)
    
    statuses = r.json()["value"]
    failed = [t["tableName"] for t in statuses
              if t["status"] != "Success"]
    notebookutils.notebook.exit(
        "OK" if not failed else "FAILED:" + ",".join(failed))

    Then in the pipeline:

    Notebook (scoped refresh)
    -> If Condition on the exit value
    -> OK      : continue to Copy data
    -> FAILED  : Fail activity with the table names

    That gives you the "continue anyway" behavior you described, but only when the tables you actually depend on have synced, rather than assuming they did because the activity ran for 12 minutes.

    Scoping each call to a few tables also means a pipeline is no longer asking for a full endpoint sync while other pipelines are still writing to the Lakehouse, which should reduce the lock contention behind these timeouts.

    So my overall approach would be:

    scoped refresh per pipeline
    -> per-table status check
    -> continue only when the tables you need are synced
    -> short retry with delay for genuine transient errors

    That keeps your pipelines independent without giving up the guarantee that downstream steps read current data.

    AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.

  • smeetsh's avatar
    smeetsh
    Icon for Continued Contributor rankContinued Contributor

    Thank you for all the responses, going down the full api/notebook route is too much of an overhead for us at the moment. It would require us to set up a service principal,  api keys etc, which we (don't) have (yet) (very small team :-) )

    We do know from experience that a 5-minute wait in our pipeline, though ugly, solved the issue. Endpoints would have synched by then. 

    (The only time that did not work flawless was on 1 pipeline that ran at 130 am in the morning, when the lakehouse was well deep asleep. I solved that by running a dummy script against the endpoint...select top (1) from etc etc.

    With that in mind I would think that (in our situation) "on completion" would be safe?

    Cheers

    Hans