<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Hi @abhijit007, Your debugging was thorough and you corre... in Data Engineering</title>
    <link>https://community.databricks.com/t5/data-engineering/databricks-app-issue-socket-hang-up-econnreset-when-api-call/m-p/150361#M53396</link>
    <description>&lt;P&gt;Hi &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/97456"&gt;@abhijit007&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;Your debugging was thorough and you correctly isolated the issue: the timeout is happening upstream of your application code. Databricks Apps run behind a managed ingress/request router that enforces request-level timeouts (typically around 30 seconds for idle connections). Because this is a platform-level gateway, no amount of configuration inside your Next.js or FastAPI code can extend it.&lt;/P&gt;
&lt;P&gt;The recommended approach is to switch from a synchronous request/response pattern to an asynchronous polling pattern (sometimes called "status pull"). Here is a concrete implementation you can adapt:&lt;/P&gt;
&lt;P&gt;FASTAPI BACKEND CHANGES&lt;/P&gt;
&lt;P&gt;Use FastAPI's BackgroundTasks to kick off the long-running agent call, store results in memory (or a more durable store), and return immediately with a task ID.&lt;/P&gt;
&lt;PRE&gt;import uuid
import asyncio
from fastapi import FastAPI, BackgroundTasks
from fastapi.responses import JSONResponse

app = FastAPI()

# In-memory task store (use Redis or a database for production)
tasks = {}

async def call_agent(task_id: str, payload: dict):
  try:
      tasks[task_id]["status"] = "processing"
      # Your existing agent call goes here
      response = await ws_openai_client.chat.completions.create(
          model="your-agent-endpoint",
          messages=payload["messages"],
      )
      tasks[task_id]["status"] = "complete"
      tasks[task_id]["result"] = response.choices[0].message.content
  except Exception as e:
      tasks[task_id]["status"] = "failed"
      tasks[task_id]["error"] = str(e)

@app.post("/api/demo/alerts")
async def start_alert(payload: dict, background_tasks: BackgroundTasks):
  task_id = str(uuid.uuid4())
  tasks[task_id] = {"status": "pending", "result": None, "error": None}
  background_tasks.add_task(call_agent, task_id, payload)
  return JSONResponse(status_code=202, content={"task_id": task_id})

@app.get("/api/demo/alerts/status/{task_id}")
async def get_alert_status(task_id: str):
  task = tasks.get(task_id)
  if not task:
      return JSONResponse(status_code=404, content={"error": "Task not found"})
  return task&lt;/PRE&gt;
&lt;P&gt;NEXT.JS FRONTEND CHANGES&lt;/P&gt;
&lt;P&gt;Poll the status endpoint every few seconds until the result is ready.&lt;/P&gt;
&lt;PRE&gt;async function fetchAlertData(payload) {
// 1. Start the task
const startRes = await fetch("/api/demo/alerts", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(payload),
});
const { task_id } = await startRes.json();

// 2. Poll for completion
while (true) {
  await new Promise((r) =&amp;gt; setTimeout(r, 3000)); // poll every 3 seconds
  const statusRes = await fetch(`/api/demo/alerts/status/${task_id}`);
  const statusData = await statusRes.json();

  if (statusData.status === "complete") {
    return statusData.result;
  }
  if (statusData.status === "failed") {
    throw new Error(statusData.error || "Agent call failed");
  }
  // Otherwise still "pending" or "processing", keep polling
}
}&lt;/PRE&gt;
&lt;P&gt;ALTERNATIVE: SERVER-SENT EVENTS (SSE)&lt;/P&gt;
&lt;P&gt;If the Databricks Apps ingress supports streaming responses (where bytes are being sent continuously), you can use SSE instead of polling. SSE keeps the connection alive by sending incremental data, which can prevent the idle-connection timeout from firing:&lt;/P&gt;
&lt;PRE&gt;from fastapi.responses import StreamingResponse
import json, asyncio

@app.post("/api/demo/alerts/stream")
async def stream_alert(payload: dict):
  async def event_generator():
      task_id = str(uuid.uuid4())
      # Start agent call as a concurrent task
      agent_task = asyncio.create_task(call_agent(task_id, payload))
      tasks[task_id] = {"status": "pending", "result": None, "error": None}

      while not agent_task.done():
          yield f"data: {json.dumps({'status': 'processing'})}\n\n"
          await asyncio.sleep(2)

      task = tasks[task_id]
      yield f"data: {json.dumps(task)}\n\n"

  return StreamingResponse(event_generator(), media_type="text/event-stream")&lt;/PRE&gt;
&lt;P&gt;However, note that whether SSE bypasses the timeout depends on the specific ingress behavior. The polling approach is the safest and most widely supported pattern.&lt;/P&gt;
&lt;P&gt;KEY POINTS&lt;/P&gt;
&lt;P&gt;1. The ~30-second cutoff is enforced by the Databricks Apps managed ingress router, not by your application frameworks.&lt;/P&gt;
&lt;P&gt;2. The polling pattern is the standard recommendation for any Databricks App workload that exceeds the gateway timeout.&lt;/P&gt;
&lt;P&gt;3. For production use, consider replacing the in-memory tasks dictionary with something persistent (Redis, a Delta table, or even a simple SQLite database) so that results survive app restarts.&lt;/P&gt;
&lt;P&gt;4. You can also look at Databricks Apps documentation for additional guidance on configuring compute size and app architecture:&lt;BR /&gt;
&lt;A href="https://docs.databricks.com/en/dev-tools/databricks-apps/index.html" target="_blank"&gt;https://docs.databricks.com/en/dev-tools/databricks-apps/index.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;* This reply used an agent system I built to research and draft this response based on the wide set of documentation I have available and previous memory. I personally review the draft for any obvious issues and for monitoring system reliability and update it when I detect any drift, but there is still a small chance that something is inaccurate, especially if you are experimenting with brand new features.&lt;/P&gt;
&lt;P&gt;If this answer resolves your question, could you mark it as "Accept as Solution"? That helps other users quickly find the correct fix.&lt;/P&gt;</description>
    <pubDate>Mon, 09 Mar 2026 06:00:20 GMT</pubDate>
    <dc:creator>SteveOstrowski</dc:creator>
    <dc:date>2026-03-09T06:00:20Z</dc:date>
    <item>
      <title>Databricks App Issue– “socket hang up / ECONNRESET” when API call runs &gt; 30 seconds</title>
      <link>https://community.databricks.com/t5/data-engineering/databricks-app-issue-socket-hang-up-econnreset-when-api-call/m-p/149966#M53213</link>
      <description>&lt;P&gt;&lt;STRONG&gt;&lt;FONT color="#008080"&gt;Problem Statement:&lt;/FONT&gt;&lt;BR /&gt;&lt;/STRONG&gt;We are running a Data App on Databricks that uses Next.js (frontend) and FastAPI (backend). The backend calls a Databricks Agent (AgentBricks) via a serving endpoint, which typically needs ~1 minute to return a response. However, any request that takes &amp;gt; ~30 seconds results in:&lt;BR /&gt;&lt;STRONG&gt;Error:&lt;/STRONG&gt; &lt;FONT face="arial black,avant garde" color="#800000"&gt;socket hang up { code: 'ECONNRESET' }&lt;BR /&gt;&lt;/FONT&gt;This happens consistently and before the Agent finishes processing.&lt;/P&gt;&lt;P&gt;&lt;FONT color="#008080"&gt;&lt;STRONG&gt;What We Are Trying To Do ::&lt;BR /&gt;&lt;/STRONG&gt;&lt;/FONT&gt;We’re simply trying to display the agent’s response in the frontend. The frontend makes a request:&lt;BR /&gt;Next.js → FastAPI → Databricks AgentBricks endpoint → FastAPI → Next.js&lt;/P&gt;&lt;P&gt;The expectation is that long-running agent responses (45–60 sec) should return normally through the API chain.&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&lt;FONT color="#008080"&gt;&lt;STRONG&gt;What We Tried ::&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;1. Route timeout configuration in Next.js&lt;BR /&gt;&lt;/STRONG&gt;Set long server execution time:&lt;BR /&gt;export const maxDuration = 300;&lt;BR /&gt;export const runtime = "nodejs";&lt;BR /&gt;&lt;BR /&gt;Configures OK, but Next.js still disconnects at ~30 seconds.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;2. FastAPI timeout controls&lt;BR /&gt;&lt;/STRONG&gt;Set timeout in OpenAI/DBR client to 300s:&lt;/P&gt;&lt;P&gt;ws_openai_client = AsyncOpenAI(&lt;BR /&gt;api_key=DATABRICKS_PAT_TOKEN,&lt;BR /&gt;base_url=BASE_URL + "/serving-endpoints",&lt;BR /&gt;timeout=300.0&lt;BR /&gt;)&lt;/P&gt;&lt;P&gt;FastAPI is NOT timing out, meaning the reset occurs before the Python layer gets a chance to respond.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;3. Artificial delay test&lt;BR /&gt;&lt;/STRONG&gt;To isolate the issue, we added a 60-second sleep:&lt;BR /&gt;&lt;BR /&gt;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/87269"&gt;@app&lt;/a&gt;.post("/api/demo/alerts")&lt;BR /&gt;def get_alert_data(payload):&lt;BR /&gt;time.sleep(60)&lt;BR /&gt;return {...}&lt;/P&gt;&lt;P&gt;Result: Next.js → FastAPI request still dies at ~30 seconds Confirms the problem is NOT related to the agent or Databricks model serving.&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;4. Simplified Agent Prompt:&lt;BR /&gt;&lt;/STRONG&gt;A lightweight prompt that finishes &amp;lt; 30 seconds works fine.&lt;BR /&gt;Confirms timeout threshold is the limiting factor.&lt;/P&gt;&lt;P&gt;&lt;FONT color="#008080"&gt;&lt;STRONG&gt;&lt;BR /&gt;Observation:&lt;BR /&gt;&lt;/STRONG&gt;&lt;/FONT&gt;The request is being terminated before FastAPI finishes processing and before the Databricks agent responds. FastAPI continues running normally in the background, which means the timeout is happening upstream of the Python backend.&lt;/P&gt;</description>
      <pubDate>Fri, 06 Mar 2026 08:55:25 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/databricks-app-issue-socket-hang-up-econnreset-when-api-call/m-p/149966#M53213</guid>
      <dc:creator>abhijit007</dc:creator>
      <dc:date>2026-03-06T08:55:25Z</dc:date>
    </item>
    <item>
      <title>Re: Databricks App Issue– “socket hang up / ECONNRESET” when API call runs &gt; 30 seconds</title>
      <link>https://community.databricks.com/t5/data-engineering/databricks-app-issue-socket-hang-up-econnreset-when-api-call/m-p/150013#M53223</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Summary:&lt;/STRONG&gt; The &lt;CODE&gt;ECONNRESET&lt;/CODE&gt; error at ~30 seconds is caused by the Databricks Apps managed ingress request router, which strictly terminates long-running synchronous HTTP requests to protect platform stability. Local framework configurations (like Next.js &lt;CODE&gt;maxDuration&lt;/CODE&gt; or FastAPI timeouts) apply only to the container and cannot override these platform-level gateway limits. To fix this, Databricks best practices dictate implementing an asynchronous "status pull" (polling) pattern.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Why Your App is Disconnecting&lt;/STRONG&gt; Databricks Apps operate within a managed Serverless Compute Plane and sit behind a Databricks-controlled Request Router. This routing layer actively monitors connection health and enforces strict timeouts on synchronous requests (often dropping them if no data is passed within ~30-120 seconds). When your Next.js frontend waits synchronously for FastAPI (which is in turn waiting ~60 seconds for the AgentBricks endpoint), the Databricks ingress proxy assumes the connection has hung and forces a disconnect (&lt;CODE&gt;ECONNRESET&lt;/CODE&gt;). Because the timeout happens upstream at the proxy layer, your FastAPI process remains unaware and finishes the task normally in the background.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The Recommended Solution: "Status Pull" Pattern&lt;/STRONG&gt; To accommodate workloads like long-running AI agents that exceed gateway timeout thresholds, you must re-architect the interaction between Next.js and FastAPI to use an asynchronous polling model:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Trigger and Return:&lt;/STRONG&gt; Update your initial FastAPI endpoint (&lt;CODE&gt;/api/demo/alerts&lt;/CODE&gt;) so that it kicks off the AgentBricks call as a background task. It should immediately respond to Next.js with an HTTP 202 (Accepted) status and a unique &lt;CODE&gt;task_id&lt;/CODE&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Implement a Status Endpoint:&lt;/STRONG&gt; Create a secondary FastAPI endpoint (e.g., &lt;CODE&gt;/api/demo/alerts/status/{task_id}&lt;/CODE&gt;) that checks the state of the background task (e.g., pending, processing, or complete).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Poll from Next.js:&lt;/STRONG&gt; Configure your Next.js frontend to periodically ping the status endpoint (for example, every 3–5 seconds) until the Agent finishes processing and the final response payload is ready to be fetched and displayed.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;This pattern circumvents the platform's ingress timeout limits, frees up UI threads, and is the standard runtime performance recommendation for heavy or long-running tasks on Databricks Apps.&lt;/P&gt;</description>
      <pubDate>Fri, 06 Mar 2026 15:53:12 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/databricks-app-issue-socket-hang-up-econnreset-when-api-call/m-p/150013#M53223</guid>
      <dc:creator>Lu_Wang_ENB_DBX</dc:creator>
      <dc:date>2026-03-06T15:53:12Z</dc:date>
    </item>
    <item>
      <title>Hi @abhijit007, Your debugging was thorough and you corre...</title>
      <link>https://community.databricks.com/t5/data-engineering/databricks-app-issue-socket-hang-up-econnreset-when-api-call/m-p/150361#M53396</link>
      <description>&lt;P&gt;Hi &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/97456"&gt;@abhijit007&lt;/a&gt;,&lt;/P&gt;
&lt;P&gt;Your debugging was thorough and you correctly isolated the issue: the timeout is happening upstream of your application code. Databricks Apps run behind a managed ingress/request router that enforces request-level timeouts (typically around 30 seconds for idle connections). Because this is a platform-level gateway, no amount of configuration inside your Next.js or FastAPI code can extend it.&lt;/P&gt;
&lt;P&gt;The recommended approach is to switch from a synchronous request/response pattern to an asynchronous polling pattern (sometimes called "status pull"). Here is a concrete implementation you can adapt:&lt;/P&gt;
&lt;P&gt;FASTAPI BACKEND CHANGES&lt;/P&gt;
&lt;P&gt;Use FastAPI's BackgroundTasks to kick off the long-running agent call, store results in memory (or a more durable store), and return immediately with a task ID.&lt;/P&gt;
&lt;PRE&gt;import uuid
import asyncio
from fastapi import FastAPI, BackgroundTasks
from fastapi.responses import JSONResponse

app = FastAPI()

# In-memory task store (use Redis or a database for production)
tasks = {}

async def call_agent(task_id: str, payload: dict):
  try:
      tasks[task_id]["status"] = "processing"
      # Your existing agent call goes here
      response = await ws_openai_client.chat.completions.create(
          model="your-agent-endpoint",
          messages=payload["messages"],
      )
      tasks[task_id]["status"] = "complete"
      tasks[task_id]["result"] = response.choices[0].message.content
  except Exception as e:
      tasks[task_id]["status"] = "failed"
      tasks[task_id]["error"] = str(e)

@app.post("/api/demo/alerts")
async def start_alert(payload: dict, background_tasks: BackgroundTasks):
  task_id = str(uuid.uuid4())
  tasks[task_id] = {"status": "pending", "result": None, "error": None}
  background_tasks.add_task(call_agent, task_id, payload)
  return JSONResponse(status_code=202, content={"task_id": task_id})

@app.get("/api/demo/alerts/status/{task_id}")
async def get_alert_status(task_id: str):
  task = tasks.get(task_id)
  if not task:
      return JSONResponse(status_code=404, content={"error": "Task not found"})
  return task&lt;/PRE&gt;
&lt;P&gt;NEXT.JS FRONTEND CHANGES&lt;/P&gt;
&lt;P&gt;Poll the status endpoint every few seconds until the result is ready.&lt;/P&gt;
&lt;PRE&gt;async function fetchAlertData(payload) {
// 1. Start the task
const startRes = await fetch("/api/demo/alerts", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify(payload),
});
const { task_id } = await startRes.json();

// 2. Poll for completion
while (true) {
  await new Promise((r) =&amp;gt; setTimeout(r, 3000)); // poll every 3 seconds
  const statusRes = await fetch(`/api/demo/alerts/status/${task_id}`);
  const statusData = await statusRes.json();

  if (statusData.status === "complete") {
    return statusData.result;
  }
  if (statusData.status === "failed") {
    throw new Error(statusData.error || "Agent call failed");
  }
  // Otherwise still "pending" or "processing", keep polling
}
}&lt;/PRE&gt;
&lt;P&gt;ALTERNATIVE: SERVER-SENT EVENTS (SSE)&lt;/P&gt;
&lt;P&gt;If the Databricks Apps ingress supports streaming responses (where bytes are being sent continuously), you can use SSE instead of polling. SSE keeps the connection alive by sending incremental data, which can prevent the idle-connection timeout from firing:&lt;/P&gt;
&lt;PRE&gt;from fastapi.responses import StreamingResponse
import json, asyncio

@app.post("/api/demo/alerts/stream")
async def stream_alert(payload: dict):
  async def event_generator():
      task_id = str(uuid.uuid4())
      # Start agent call as a concurrent task
      agent_task = asyncio.create_task(call_agent(task_id, payload))
      tasks[task_id] = {"status": "pending", "result": None, "error": None}

      while not agent_task.done():
          yield f"data: {json.dumps({'status': 'processing'})}\n\n"
          await asyncio.sleep(2)

      task = tasks[task_id]
      yield f"data: {json.dumps(task)}\n\n"

  return StreamingResponse(event_generator(), media_type="text/event-stream")&lt;/PRE&gt;
&lt;P&gt;However, note that whether SSE bypasses the timeout depends on the specific ingress behavior. The polling approach is the safest and most widely supported pattern.&lt;/P&gt;
&lt;P&gt;KEY POINTS&lt;/P&gt;
&lt;P&gt;1. The ~30-second cutoff is enforced by the Databricks Apps managed ingress router, not by your application frameworks.&lt;/P&gt;
&lt;P&gt;2. The polling pattern is the standard recommendation for any Databricks App workload that exceeds the gateway timeout.&lt;/P&gt;
&lt;P&gt;3. For production use, consider replacing the in-memory tasks dictionary with something persistent (Redis, a Delta table, or even a simple SQLite database) so that results survive app restarts.&lt;/P&gt;
&lt;P&gt;4. You can also look at Databricks Apps documentation for additional guidance on configuring compute size and app architecture:&lt;BR /&gt;
&lt;A href="https://docs.databricks.com/en/dev-tools/databricks-apps/index.html" target="_blank"&gt;https://docs.databricks.com/en/dev-tools/databricks-apps/index.html&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;* This reply used an agent system I built to research and draft this response based on the wide set of documentation I have available and previous memory. I personally review the draft for any obvious issues and for monitoring system reliability and update it when I detect any drift, but there is still a small chance that something is inaccurate, especially if you are experimenting with brand new features.&lt;/P&gt;
&lt;P&gt;If this answer resolves your question, could you mark it as "Accept as Solution"? That helps other users quickly find the correct fix.&lt;/P&gt;</description>
      <pubDate>Mon, 09 Mar 2026 06:00:20 GMT</pubDate>
      <guid>https://community.databricks.com/t5/data-engineering/databricks-app-issue-socket-hang-up-econnreset-when-api-call/m-p/150361#M53396</guid>
      <dc:creator>SteveOstrowski</dc:creator>
      <dc:date>2026-03-09T06:00:20Z</dc:date>
    </item>
  </channel>
</rss>

