Repository navigation
Description
Summary
When a PFCP Session Deletion Request times out (No PFCP session deletion response) and the associated SBI stream has already been released, sess_5gc_timeout() in src/smf/pfcp-path.c hits ogs_assert(stream) and aborts the whole SMF process. On restart the SMF loses all in-memory UE address allocations, which leads to duplicate UE IP assignment and broken downlink for roughly half of the (re)attached sessions. Under session churn (mass UE attach/detach) this can become a self-feeding crash loop (crash → reconciliation → more deletion timeouts → crash again).
This is the sibling of #2085 (which fixed the same pattern for the modification timeout path); the deletion path was left unguarded.
Environment
- open5gs commit
f87da618b5896f57c3a2bacc7e011974403c4d28— still present onmainas of 2026-10-03 - N4 peer: eUPF (edgecomllc/eupf), ~600–1100 simulated UEs on the same host
- Lab rig with heavy session churn; open5gs SMF restarted 4–6 times within one afternoon, every restart triggered by this assert
Evidence
[pfcp] WARNING: [1289] LOCAL No Reponse. Give up! for step 1 type 54 peer [172.22.0.8]:8805 (../lib/pfcp/xact.c:640)
[smf] ERROR: [imsi-001010000082236:2] No PFCP session deletion response[7] (../src/smf/pfcp-path.c:330)
[smf] FATAL: sess_5gc_timeout: Assertion `stream' failed. (../src/smf/pfcp-path.c:341)
[core] FATAL: backtrace() returned 8 addresses (../lib/core/ogs-abort.c:37)
./open5gs-smfd(+0x4f730) ...
Root cause
src/smf/pfcp-path.c, sess_5gc_timeout():
} else if (trigger == OGS_PFCP_DELETE_TRIGGER_UE_REQUESTED ||
trigger == OGS_PFCP_DELETE_TRIGGER_AMF_UPDATE_SM_CONTEXT ||
trigger == OGS_PFCP_DELETE_TRIGGER_AMF_RELEASE_SM_CONTEXT) {
ogs_assert(stream); /* <-- stream may be NULL */
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL, strerror,
NULL, NULL));
}stream comes from ogs_sbi_stream_find_by_id(xact->assoc_stream_id). If the AMF-side SBI stream was released while the PFCP transaction was still pending (AMF gave up / UE context cleaned up during churn), the lookup returns NULL and the assert aborts the process. The modification branch a few lines above already guards with if (stream), so this looks like an oversight rather than intentional behavior.
Suggested fix
Handle the NULL stream gracefully — report 504 only when the stream is still alive, otherwise log and continue with the existing SMF_EVT_N4_TIMER cleanup below:
if (stream) {
ogs_assert(true ==
ogs_sbi_server_send_error(stream,
OGS_SBI_HTTP_STATUS_GATEWAY_TIMEOUT, NULL, strerror,
NULL, NULL));
} else {
ogs_warn("No SBI stream for PFCP deletion timeout [%d]", trigger);
}Verification of the fix
We applied exactly this change to our local build and re-ran the scenario: full stack reset + a one-shot 600-UE attach/detach churn plus mass UE kills. SMF restart count stayed 0 through the whole run (previously 4–6 crashes per run), with clean 1:1 UE IP allocation. A PR can be provided if helpful.
Notes
- The timeout itself can also be triggered by a UPF not answering some deletions; that part is being reported separately to eUPF (edgecomllc/eupf). Regardless of peer behavior, the SMF should not abort on this path.
Activity
core: always send PFCP responses; absorb absent datapath entries in m…
core: always send PFCP responses; absorb absent datapath entries in m…
core: always send PFCP responses; absorb absent datapath entries in m…
pespin commentedon Oct 13, 2026
I just run on to this same issue while running some TTCN-3 tests, and I was going to fix it but luckily I did "git pull" before and found out to my surprise that the issue was already fixed :)
I confirm with b50611f it didn't crash again.
smf: do not abort on PFCP deletion timeout when the SBI stream is gone