You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PFCP responses are silently dropped when a handler returns an error (Session Deletion Response lost after "delete: key does not exist") #647
PfcpHandlerMap.Handle() returns early when a handler reports an error and silently discards the response message the handler just built. The most visible case is the Session Deletion path: HandlePfcpSessionDeletionRequest() → deletePDR() hits Can't delete GTP PDR: delete: key does not exist (the datapath entry is already gone; cilium/ebpf surfaces ENOENT), the handler returns (SessionDeletionResponse(cause=RuleCreationModificationFailure), err), and the response is never transmitted.
Per PFCP (TS 29.244) the UP function must answer every received request. Without a response, the CP function (e.g. open5gs SMF) times out its PFCP transaction — on some open5gs versions this even aborts the entire SMF process (sess_5gc_timeout: Assertion 'stream' failed), so this can cascade into a core-network outage.
Environment / evidence
eUPF commit 241af932 — both defects are still present on main as of 2026-10-03
cmd/core/pdr_creation_context.godeletePDR() (and the FAR/QER delete loops in HandlePfcpSessionDeletionRequest) treat "entry already absent" (ENOENT / "key does not exist") as a hard failure, even though the desired end state of a delete is precisely “absent”.
Related but different root cause: #527 ("Can't delete PDR with v0.6.0", closed as fixed in v0.6.1) — the current main can still reproduce deletion failures + missing responses as above.
Suggested fix
Always transmit outgoingMsg when non-nil, regardless of the handler's error (log the send error if any).
Tolerate ENOENT on datapath deletes — treat "key does not exist" as success (optionally log at debug level).
Verification
We run a locally patched build with the two changes above. Same workload afterwards:
Summary: Handle() now always transmits the handler's response when non-nil (send errors only logged), and deletePDR() / FAR / QER deletes treat ENOENT ("key does not exist") as success via a new isDataplaneKeyAbsent() helper.
Verified on our churn workload: after the patch, every Session Deletion Request is answered (rx=7/tx=7, all RequestAccepted, no Error handling PFCP warnings). Happy to adjust if you'd prefer different semantics (e.g. keeping the failure cause but still sending the response).
Activity
pirog-spb commentedon Oct 3, 2026
Hi @zhangerfei-dp ,
Thanks for the detailed description. A PR would be very helpful.
-- BR, Alex
zhangerfei-dp commentedon Oct 3, 2026
Thanks Alex! The PR is up: #650
Summary:
Handle()now always transmits the handler's response when non-nil (send errors only logged), anddeletePDR()/ FAR / QER deletes treat ENOENT ("key does not exist") as success via a newisDataplaneKeyAbsent()helper.Verified on our churn workload: after the patch, every Session Deletion Request is answered (rx=7/tx=7, all
RequestAccepted, noError handling PFCPwarnings). Happy to adjust if you'd prefer different semantics (e.g. keeping the failure cause but still sending the response).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…