{"record":{"id":"38668895786ad471","repo":"cloudflare/pingora","slug":"custom-proxy-task-api-not-implemented","errorCode":null,"errorMessage":"Custom proxy task API not implemented","messagePattern":"Custom proxy task API not implemented","errorType":"panic","errorClass":"panic","httpStatus":null,"severity":"error","filePath":"pingora-core/src/protocols/http/custom/server.rs","lineNumber":90,"sourceCode":"    ///\n    /// # Panics\n    /// Panics if the Custom session does not implement the proxy task API.\n    #[track_caller]\n    fn send_proxy_task(&mut self, _task: HttpTask) {\n        panic!(\"Custom proxy task API not implemented\")\n    }\n\n    /// Whether there are pending proxy tasks queued for writing.\n    fn has_pending_proxy_tasks(&self) -> bool {\n        false\n    }\n\n    /// Write queued proxy tasks in a cancel-safe manner.\n    ///\n    /// # Panics\n    /// Panics if the Custom session does not implement the proxy task API.\n    fn write_proxy_tasks(&mut self) -> impl Future<Output = Result<bool>> + Send {\n        async { panic!(\"Custom proxy task API not implemented\") }\n    }\n\n    fn set_read_timeout(&mut self, timeout: Option<Duration>);\n\n    fn get_read_timeout(&self) -> Option<Duration>;\n\n    fn set_write_timeout(&mut self, timeout: Option<Duration>);\n\n    fn get_write_timeout(&self) -> Option<Duration>;\n\n    fn set_total_drain_timeout(&mut self, timeout: Option<Duration>);\n\n    fn get_total_drain_timeout(&self) -> Option<Duration>;\n\n    fn request_summary(&self) -> String;\n\n    fn response_written(&self) -> Option<&ResponseHeader>;\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/cloudflare/pingora/blob/4487f7b2ab50f159e4a2cf4f6a6b813f61bb6e19/pingora-core/src/protocols/http/custom/server.rs#L72-L108","documentation":"`write_proxy_tasks` is a default method on the `Custom` session trait in pingora-core that unconditionally panics. It exists so implementors of custom protocols only pay for the proxy-task API if they use it: the default body panics with \"Custom proxy task API not implemented\" to signal that this custom session does not support queuing HTTP proxy tasks. The panic is documented and expected whenever the proxy-task path is exercised on a session that never overrode the method.","triggerScenarios":"Using a `custom` protocol session (from `pingora-core/src/protocols/http/custom/server.rs`) in a context that calls `write_proxy_tasks` — e.g., routing a custom-protocol connection through HTTP proxy task writing — without the trait implementor overriding `write_proxy_tasks` with a real implementation.","commonSituations":"Configuring a Pingora app with a custom protocol listener but letting the generic proxy pipeline (which expects HTTP proxy tasks) drive the session; upgrading Pingora and new proxy-task code paths now reaching the custom session default; implementing `Custom` for a protocol that has no notion of HTTP proxy tasks and then using it with `proxy_to_upstream`-style APIs.","solutions":["Do not drive custom-protocol sessions through the HTTP proxy-task API; handle them with the custom session's own read/write methods and return the response directly.","If proxy tasks are needed, override `write_proxy_tasks` (and related proxy-task methods) in your `Custom` trait implementation with a real protocol-specific implementation.","Ensure the server/handoff logic selects the HTTP session type (h1/h2) rather than the custom session type when proxy-task behavior is required."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Before routing a session through proxy-task APIs, confirm it is not a Custom session\nfn supports_proxy_tasks(session: &Session) -> bool {\n    !matches!(session.as_downstream(), /* custom protocol session */ _ if is_custom(session))\n}","typeGuard":"fn is_custom_session(s: &Session) -> bool {\n    // narrow by the concrete downstream/session enum variant for the custom protocol\n    matches!(s.as_downstream(), DownstreamSession::Custom(_))\n}","tryCatchPattern":null,"preventionTips":["Never route custom-protocol connections through the generic HTTP proxy-task pipeline.","If your protocol needs proxy tasks, override `write_proxy_tasks` and the related proxy-task trait methods.","Check the configured protocol type (http(s) vs custom) before selecting the proxy code path.","Pin and review Pingora upgrades for new calls into default trait methods on custom sessions."],"tags":["panic","trait-default","custom-protocol","not-implemented"],"backgroundTag":"method-not-implemented","analyzedSha":"4487f7b2ab50f159e4a2cf4f6a6b813f61bb6e19","analyzedAt":"2026-09-13T07:48:52.011Z","contentChangedAt":"2026-09-13T07:48:52.011Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}