{"record":{"id":"94d39e7dcbfe07fb","repo":"linera-io/linera-protocol","slug":"serviceoracleresponsetoolarge","errorCode":"ServiceOracleResponseTooLarge","errorMessage":"ExecutionError::ServiceOracleResponseTooLarge","messagePattern":"ExecutionError::ServiceOracleResponseTooLarge","errorType":"exception","errorClass":"ExecutionError","httpStatus":null,"severity":"error","filePath":"linera-execution/src/resources.rs","lineNumber":815,"sourceCode":"        let spent_execution_time = &mut tracker.service_oracle_execution;\n        let limit = Duration::from_millis(self.policy.maximum_service_oracle_execution_ms);\n\n        *spent_execution_time = spent_execution_time.saturating_add(execution_time);\n\n        ensure!(\n            *spent_execution_time < limit,\n            ExecutionError::MaximumServiceOracleExecutionTimeExceeded\n        );\n\n        Ok(())\n    }\n\n    /// Tracks the size of a response produced by an oracle.\n    pub(crate) fn track_service_oracle_response(\n        &self,\n        response_bytes: usize,\n    ) -> Result<(), ExecutionError> {\n        ensure!(\n            response_bytes as u64 <= self.policy.maximum_oracle_response_bytes,\n            ExecutionError::ServiceOracleResponseTooLarge\n        );\n\n        Ok(())\n    }\n}\n\nimpl<Account, Tracker> ResourceController<Account, Tracker>\nwhere\n    Tracker: AsMut<ResourceTracker>,\n{\n    /// Tracks the serialized size of a block, or parts of it.\n    pub fn track_block_size_of(&mut self, data: &impl Serialize) -> Result<(), ExecutionError> {\n        self.track_block_size(bcs::serialized_size(data)?)\n    }\n\n    /// Tracks the serialized size of a block, or parts of it.","sourceCodeStart":797,"sourceCodeEnd":833,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-execution/src/resources.rs#L797-L833","documentation":"Every oracle response is size-checked by track_service_oracle_response: if the serialized response exceeds the policy's maximum_oracle_response_bytes, the query fails with ServiceOracleResponseTooLarge (resources.rs:815). Oracle responses are recorded and replayed, so their size must stay bounded.","triggerScenarios":"A service-oracle query returns a payload whose serialized size exceeds maximum_oracle_response_bytes, e.g. a query that returns a whole table, a large collection, or an unbounded result set.","commonSituations":"Queries returning all items instead of a page; missing pagination; page size configured above the policy; policies lowered between epochs; returning file-like payloads in a query response.","solutions":["Paginate or project the response: return only the needed fields and rows per query","Move large payloads out of band via blobs and return only a BlobId or hash from the query","If you operate the network, raise maximum_oracle_response_bytes in the committee policy"],"exampleFix":"// before\nfn handle_query(_: Query) -> Response { Response::All(self.items.clone()) }\n\n// after\nfn handle_query(q: Query) -> Response {\n    Response::Page(self.items.iter().skip(q.offset).take(q.limit).cloned().collect())\n}","handlingStrategy":"validation","validationCode":"// Validate the serialized response size before returning from the service handler\nfn response_fits(resp: &Response, policy: &ResourceControlPolicy) -> Result<bool, Error> {\n    Ok(bcs::serialized_size(resp)? as u64 <= policy.maximum_oracle_response_bytes)\n}\n\nlet resp = self.handle_query(q)?;\nif !response_fits(&resp, policy)? {\n    return Err(app_error!(\"query response exceeds oracle size limit; paginate\"));\n}","typeGuard":"fn is_oracle_response_too_large(err: &ExecutionError) -> bool {\n    matches!(err, ExecutionError::ServiceOracleResponseTooLarge)\n}","tryCatchPattern":"match contract.call_service_oracle(app_id, query).await {\n    Ok(bytes) => bytes,\n    Err(ref e) if is_oracle_response_too_large(e) => {\n        // deterministic: re-ask with pagination instead of retrying as-is\n        contract.call_service_oracle(app_id, paginated(query, 0, page_size)).await\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Paginate every query that can return unbounded collections","Return blob ids or hashes for large payloads, not the payload itself","Assert serialized response sizes in service unit tests against the policy limit"],"tags":["service-oracle","response-size","resource-limits","linera"],"backgroundTag":"response-too-large","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}