{"id":"CVE-2026-116774","revision":null,"records":[{"revision":"c62ab083ca8f4edb9ea0a60cb04648b3","observedAt":"2026-10-28T17:46:48.824+00:00","statement":{"source":"cve-program","id":"CVE-2026-116774","aliases":[],"title":"russh: peer-declared zero maximum packet size permanently stalls channel writes (silent AsyncWrite hang)","description":"russh is a Rust SSH client and server library that includes an SSH agent protocol implementation. From 0.60.0 until 0.65.0, channel-open parsing accepts a peer-declared maximum_packet_size of zero and passes it into ChannelTx::poll_writable in russh/src/channels/io/tx.rs. The Channel::data, Channel::make_writer, and Channel::into_stream asynchronous write paths then calculate a writable size of zero and remain pending forever because window adjustments cannot satisfy a static zero packet maximum. An authenticated client can strand server writes, and a malicious server can strand client writes, allowing affected tasks, channels, and connections to accumulate without surfacing an error. This issue is fixed in version 0.65.0.","state":0,"publishedAt":"2026-10-27T20:25:26.914+00:00","modifiedAt":"2026-10-28T16:13:18.607+00:00","affected":[{"ecosystem":"Vendor product","name":"russh","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"Eugeny\",\n                    \"product\": \"russh\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 0.60.0, < 0.65.0\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","score":4.3,"severity":"MEDIUM"}],"references":["https://github.com/Eugeny/russh/security/advisories/GHSA-fw5c-8223-6h42","https://github.com/Eugeny/russh/commit/39cb9dbaa37caf555d34c6c22efa3bbbff9e186c","https://github.com/Eugeny/russh/releases/tag/v0.65.0"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-116774","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-116774","identifiers":["CVE-2026-116774"]},"retained":false,"historicalAffected":[]},{"revision":"73394bfa1c62456f9d2457dfa0d7e0db","observedAt":"2026-10-30T23:48:09.501+00:00","statement":{"source":"euvd","id":"EUVD-2026-111389","aliases":["CVE-2026-116774"],"title":"russh is a Rust SSH client and server library that includes an SSH agent protocol implementation. From 0.60.0 until 0.65.0, channel-open parsing accepts a peer-declared maximum_packet_size of zero and passes it into ChannelTx::poll_writable…","description":"russh is a Rust SSH client and server library that includes an SSH agent protocol implementation. From 0.60.0 until 0.65.0, channel-open parsing accepts a peer-declared maximum_packet_size of zero and passes it into ChannelTx::poll_writable in russh/src/channels/io/tx.rs. The Channel::data, Channel::make_writer, and Channel::into_stream asynchronous write paths then calculate a writable size of zero and remain pending forever because window adjustments cannot satisfy a static zero packet maximum. An authenticated client can strand server writes, and a malicious server can strand client writes, allowing affected tasks, channels, and connections to accumulate without surfacing an error. This issue is fixed in version 0.65.0.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","score":4.3,"severity":null}],"references":["https://github.com/Eugeny/russh/security/advisories/GHSA-fw5c-8223-6h42","https://github.com/Eugeny/russh/commit/39cb9dbaa37caf555d34c6c22efa3bbbff9e186c","https://github.com/Eugeny/russh/releases/tag/v0.65.0"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-111389","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Oct 27, 2026, 8:25:26 PM","dateUpdated":"Oct 28, 2026, 4:13:18 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-111389","identifiers":["EUVD-2026-111389","CVE-2026-116774"]},"retained":false,"historicalAffected":[]},{"revision":"474fe004bcf0471e93b8cc511e2e1543","observedAt":"2026-10-30T23:47:40.018+00:00","statement":{"source":"nvd","id":"CVE-2026-116774","aliases":[],"title":"russh is a Rust SSH client and server library that includes an SSH agent protocol implementation. From 0.60.0 until 0.65.0, channel-open parsing accepts a peer-declared maximum_packet_size of zero and passes it into ChannelTx::poll_writable…","description":"russh is a Rust SSH client and server library that includes an SSH agent protocol implementation. From 0.60.0 until 0.65.0, channel-open parsing accepts a peer-declared maximum_packet_size of zero and passes it into ChannelTx::poll_writable in russh/src/channels/io/tx.rs. The Channel::data, Channel::make_writer, and Channel::into_stream asynchronous write paths then calculate a writable size of zero and remain pending forever because window adjustments cannot satisfy a static zero packet maximum. An authenticated client can strand server writes, and a malicious server can strand client writes, allowing affected tasks, channels, and connections to accumulate without surfacing an error. This issue is fixed in version 0.65.0.","state":0,"publishedAt":"2026-10-27T21:18:05.933+00:00","modifiedAt":"2026-10-28T17:18:06.99+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","score":4.3,"severity":"MEDIUM"}],"references":["https://github.com/Eugeny/russh/commit/39cb9dbaa37caf555d34c6c22efa3bbbff9e186c","https://github.com/Eugeny/russh/releases/tag/v0.65.0","https://github.com/Eugeny/russh/security/advisories/GHSA-fw5c-8223-6h42"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-116774","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-400","CWE-835"],"productCriteria":[],"sourceDates":{"published":"2026-10-27T21:18:05.933","lastModified":"2026-10-28T17:18:06.990"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-116774","identifiers":["CVE-2026-116774"]},"retained":false,"historicalAffected":[]},{"revision":"82053116fb094e5e8e41d7f107c65385","observedAt":"2026-10-30T23:47:35.544+00:00","statement":{"source":"osv","id":"GHSA-fw5c-8223-6h42","aliases":["CVE-2026-116774"],"title":"russh: peer-declared zero maximum packet size permanently stalls channel writes (silent AsyncWrite hang)","description":"## Summary\n\nA peer can advertise `maximum packet size = 0` in its channel-open message (`CHANNEL_OPEN` when attacking a server, `CHANNEL_OPEN_CONFIRMATION` when attacking a client). russh accepts the value without validation and copies it into the channel write state, where it caps the size of every outgoing data chunk. In the `AsyncWrite` code path (`ChannelTx::poll_writable`, used by `Channel::data()`, `Channel::make_writer()` and `Channel::into_stream()`), a cap of 0 makes every write future stay `Poll::Pending` forever: `writable = max_packet_size.min(window_size).min(buf_len)` is always 0, and no future event can ever raise it (a static maximum packet size of 0 can never be satisfied by any amount of peer-granted window). The write neither completes nor errors, so the application task hangs silently.\n\nEvery other write path in russh already treats `max_packet_size == 0` as an error (`Error::Inconsistent`): `Channel::reserve_writable_chunk` (`russh/src/channels/mod.rs:363-365`) and the session packetizers (`russh/src/session.rs:489-492` and `549-552`). The `AsyncWrite` path is the only one that lacks the guard - it contradicts the crate's own invariant.\n\n## Root cause\n\n(1) Peer value accepted without validation:\n\n- `russh/src/parsing.rs:44` (`OpenChannelMessage::parse`): `let maxpacket = map_err!(u32::decode(r))?;` stored as `recipient_maximum_packet_size` (`:25-30`); no range check. Same for `ChannelOpenConfirmation::decode` at `russh/src/parsing.rs:194-207`.\n- The only packet-size validation anywhere is an upper bound on the *local* config that merely logs (`russh/src/client/mod.rs:1189-1194`, `russh/src/server/mod.rs:912-917`). Nothing validates the peer's value - 0 passes silently.\n\n(2) The value flows into the channel write state verbatim:\n\n- Server: `russh/src/server/encrypted.rs:1877-1900` - `ChannelParams { recipient_maximum_packet_size: msg.recipient_maximum_packet_size, .. }`, then `Channel::new(..., channel_params.recipient_maximum_packet_size, ...)`.\n- Client: `russh/src/client/encrypted.rs:471-488` - `parameters.confirm(&msg)` (`russh/src/lib_inner.rs:519-523`) and `ChannelMsg::Open { max_packet_size: msg.maximum_packet_size, .. }`, consumed by `wait_channel_confirmation` (`russh/src/client/mod.rs:698-722`), which builds `ChannelWriteHalf { max_packet_size, .. }`.\n- The write half hands the value to the writer: `make_writer_ext` (`russh/src/channels/mod.rs:433-441`) and `into_stream` (`russh/src/channels/mod.rs:661-670`) pass `self.max_packet_size` to `ChannelTx::new`.\n\n(3) The hang - `russh/src/channels/io/tx.rs:82-108` (current v0.64.1, byte-identical in v0.60.0):\n\n```rust\nfn poll_writable(&mut self, cx: &mut Context<'_>, buf_len: usize) -> Poll<NonZeroUsize> {\n    ...\n    let writable = (self.max_packet_size).min(*window_size).min(buf_len as u32) as usize;\n    match NonZeroUsize::try_from(writable) {\n        Ok(w) => {\n            *window_size -= writable as u32;\n            if *window_size > 0 {\n                self.notify.notify_one();\n            }\n            Poll::Ready(w)\n        }\n        Err(_) => {\n            drop(window_size);\n            ready!(self.window_size_notication.poll_unpin(cx));\n            self.window_size_notication = WatchNotification::new(Arc::clone(&self.notify));\n            cx.waker().wake_by_ref();\n            Poll::Pending\n        }\n    }\n}\n```\n\nWith `max_packet_size == 0`, `writable` is always 0 regardless of `window_size` and `buf_len`; the task parks on the window notification, gets re-polled on every `CHANNEL_WINDOW_ADJUST`, recomputes 0, and parks again - forever.\n\n(4) The guard exists everywhere else:\n\n```rust\n// russh/src/channels/mod.rs:363-365 (used by send_bytes -> data_bytes / extended_data_bytes)\nif self.max_packet_size == 0 {\n    return Err(Error::Inconsistent);\n}\n\n// russh/src/session.rs:490-492 and :550-552 (packetizer)\nif max_packet_size == 0 {\n    return Err(crate::Error::Inconsistent);\n}\n```\n\nNote that `Channel::data(reader)` (`russh/src/channels/mod.rs:321-323`) goes through `send_data` -> `tokio::io::copy(&mut data, &mut tx)` (`:350-360`) into the same `ChannelTx`, so the primary documented data API hangs as well; only the `*_bytes` variants reach the guard.\n\n## Attack scenarios\n\n- **Server (authenticated remote DoS)**: with the default configuration, an authenticated client opens a session channel advertising `maximum packet size = 0`. Whenever the server application writes on that channel through `AsyncWrite` (echo, shell prompts, SFTP - russh's own examples echo via `into_stream()`), the write future never completes. The handler task is stranded and no error surfaces, so application cleanup paths do not trigger. Repeat per channel and per connection; keep-alive traffic resets the server `inactivity_timeout` (default 600 s), so stranded resources persist as long as the attacker wants.\n- **Client (malicious server)**: a malicious or buggy server confirms an opened channel with `maximum packet size = 0`; the client application's writes on that channel stall forever. The client `inactivity_timeout` defaults to `None`, so nothing ever tears the session down.\n- This is distinct from a `window_size == 0` stall: a zero window is dynamic flow control that a well-behaved peer releases as soon as its buffers drain, while `maximum packet size` is a static peer declaration where 0 can never be satisfied by any future packet. RFC 4254 section 5.1 recommends a minimum of 32768 - legitimate peers do not send 0.\n\n## Impact\n\nPermanent, silent denial of service for the affected writes, with stranded tasks/channels/connections that accumulate for the attacker - resource exhaustion of a server or of a client application. Because the failure mode is `Poll::Pending` instead of `Err`, ordinary application mitigations (error handling, timeouts on writes, connection teardown) do not engage on their own.\n\n## Reproducer\n\nTwo stock russh instances are enough (no raw SSH crafting required):\n\n1. Server: default config plus a host key; `channel_open_session` accepts and echoes using `tokio::io::copy` into `channel.into_stream()` (the pattern from russh's own examples).\n2. Client: default config except `config.maximum_packet_size = 0` (accepted silently; see above), then `authenticate_publickey`, `channel_open_session().await`, `channel.data(&b\"hello\"[..]).await`.\n\nThe client's `CHANNEL_OPEN` goes out with `maximum packet size = 0` (`russh/src/client/session.rs:21-44` encodes `self.common.config.maximum_packet_size` verbatim). All three scenarios below were verified end-to-end against a stock russh v0.64.1 build (ring backend), default settings otherwise:\n\n- control (both sides default, 32768): the server echoes and the client receives `hello`;\n- client `maximum_packet_size = 0`: the server prints the received bytes and then the echo write never completes - no data, no error, the client times out;\n- server `maximum_packet_size = 0`: the client's `channel.data(...)` future never completes - no error, it times out.\n\nObserved output (abridged):\n\n```\n=== SCENARIO A (control): both sides default (maxpacket 32768) ===\n[server] read 5 bytes; echoing via AsyncWrite ...\n[server] echo write completed\nRESULT A: echo received: \"hello\"\n\n=== SCENARIO B: client advertises maximum_packet_size = 0 ===\n[server] read 5 bytes; echoing via AsyncWrite ...\nRESULT B: TIMEOUT after 6s - server-side echo write is permanently stalled (no error, no data)\n\n=== SCENARIO C: server advertises maximum_packet_size = 0 ===\nRESULT C: TIMEOUT after 6s - client-side channel.data() is permanently stalled\n```\n\nThe server task stays parked inside `ChannelTx::poll_writable`; nothing is logged and nothing is returned to the handler. The harness source (server: `into_stream()` echo; client: one config toggle) can be attached on request.\n\nUnit-level sketch of the core defect:\n\n```rust\nlet mut tx = ChannelTx::<Msg>::new(\n    sender, ChannelId(0),\n    Arc::new(Mutex::new(4096)),   // window_size\n    Arc::new(Notify::new()),      // notify\n    0,                            // max_packet_size\n    None,\n);\n// poll_write(&mut tx, cx, b\"x\") stays Poll::Pending forever,\n// even after CHANNEL_WINDOW_ADJUST raises `window_size`.\n```\n\n## Suggested fix\n\n- **Validate at parse time (preferred)**: reject `maximum_packet_size == 0` with `Error::Inconsistent` in `OpenChannelMessage::parse` and `ChannelOpenConfirmation::decode` (`russh/src/parsing.rs`), consistent with the existing guards; optionally clamp any value below the RFC 4254 recommended minimum (32768) instead.\n- **Defense in depth**: in `ChannelTx::poll_writable` (`russh/src/channels/io/tx.rs:82`), when `self.max_packet_size == 0`, surface an `io::Error` from `poll_write` instead of returning `Poll::Pending`.\n\nBoth match the treatment PR #695 already applied to the other write paths in v0.61.0 (the `reserve_writable_chunk` and session packetizer guards).\n\n## Affected versions\n\nVerified by inspecting the release artifacts: **0.60.0 through 0.64.1 (current) are affected** - `poll_writable` is byte-identical in v0.60.0 and the peer-value plumbing is present in all of them. The `ChannelTx` write logic and the peer-value flow predate 0.60 (they go back to the `channels::io` refactor), so we recommend treating all releases that ship `channels::io::ChannelTx` as affected. The zero-guards in the other write paths were only added in 0.61.0, so on 0.60.x those paths do not even fail with an error.\n\n## Reporter\n\nTshellauth","state":0,"publishedAt":"2026-10-30T22:58:53+00:00","modifiedAt":"2026-10-30T23:15:05.419143+00:00","affected":[{"ecosystem":"crates.io","name":"russh","ranges":[{"type":"ECOSYSTEM","events":[{"kind":"introduced","version":"0.60.0"},{"kind":"fixed","version":"0.65"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/Eugeny/russh/security/advisories/GHSA-fw5c-8223-6h42","https://nvd.nist.gov/vuln/detail/CVE-2026-116774","https://github.com/Eugeny/russh/commit/39cb9dbaa37caf555d34c6c22efa3bbbff9e186c","https://github.com/Eugeny/russh","https://github.com/Eugeny/russh/releases/tag/v0.65.0"],"sourceUrl":"https://github.com/advisories/GHSA-fw5c-8223-6h42","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-fw5c-8223-6h42","identifiers":["GHSA-fw5c-8223-6h42","CVE-2026-116774"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-10-31T02:47:27.2544287+00:00","complete":true,"records":1766,"lastAttemptAt":"2026-10-31T02:47:27.2544287+00:00","lastSuccessAt":"2026-10-31T02:47:27.412022+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:47:27.4120229+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-9266d7b009bf9c4a0ccdcb5cbdea7f905cb3c4d92fd3b41581ece16b2cfdc4e7-d7f5a774da7dc1d7039b507f4f152d095052a9de5600b490bf90aeeb3ccce760","complete":true,"records":417488,"lastAttemptAt":"2026-10-31T02:45:38.6593437+00:00","lastSuccessAt":"2026-10-31T02:45:38.6372337+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:45:38.6593437+00:00","snapshotPublishedAt":"2026-10-31T02:28:41+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-39149994e3854f27b5e713b62480af55","complete":true,"records":13563,"lastAttemptAt":"2026-10-31T02:47:53.1518029+00:00","lastSuccessAt":"2026-10-31T00:45:56.62+00:00","error":null,"lastVerifiedAt":"2026-10-31T00:45:56.62+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13635,"expectedIdentifiers":13635,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-10-31T02:47:27.2544287+00:00","complete":true,"records":1094,"lastAttemptAt":"2026-10-31T02:47:27.2544287+00:00","lastSuccessAt":"2026-10-31T02:47:27.4127685+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:47:27.4127685+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-e07ef8e6642e41289c217437d69cabe7","complete":false,"records":13575,"lastAttemptAt":"2026-10-31T02:47:52.572535+00:00","lastSuccessAt":"2026-10-31T02:47:52.568+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:47:52.568+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13547,"expectedIdentifiers":13635,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-21dcd6662970dfea02e4ea60ee637115e8d92664947484d2b9276b3f6568a84f","complete":true,"records":9815,"lastAttemptAt":"2026-10-31T02:47:27.2108627+00:00","lastSuccessAt":"2026-10-30T23:47:34.1817587+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:47:27.2108627+00:00","snapshotPublishedAt":"2026-10-30T23:33:17+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-2de9ccc5290f060c7aa63f89c25dd76f655a64ba1aba7c05c97fa3bee4f09899","complete":true,"records":1967,"lastAttemptAt":"2026-10-31T02:45:38.7086939+00:00","lastSuccessAt":"2026-10-28T20:55:34.2982937+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:45:38.7086939+00:00","snapshotPublishedAt":"2026-10-28T20:03:08+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-f95f76cd406ae5bae3de632ad37fd2d5160b44f5e6b51748ac6f8f0c0c88e72b","complete":true,"records":3028,"lastAttemptAt":"2026-10-31T02:47:27.2247414+00:00","lastSuccessAt":"2026-10-30T23:47:38.4914494+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:47:27.2247414+00:00","snapshotPublishedAt":"2026-10-30T23:18:12+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-0d73c5ef3fc1482e9579e6438c4ee3a6c6252dd519f22ac62df687497937bd6c","complete":true,"records":230992,"lastAttemptAt":"2026-10-31T02:47:27.0834272+00:00","lastSuccessAt":"2026-10-31T02:47:25.6622408+00:00","error":null,"lastVerifiedAt":"2026-10-31T02:47:27.0834272+00:00","snapshotPublishedAt":"2026-10-31T02:33:22+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}