{"record":{"id":"47586af41d2cca82","repo":"quickwit-oss/quickwit","slug":"max-grpc-message-size-grpc-max-message-size-mu","errorCode":null,"errorMessage":"max gRPC message size (`grpc.max_message_size`) must be at least 1MB, got `{}`","messagePattern":"max gRPC message size \\(`grpc\\.max_message_size`\\) must be at least 1MB, got `(.+?)`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-config/src/node_config/mod.rs","lineNumber":130,"sourceCode":"    // should be idle before sending a keepalive ping.\n    #[serde(default = \"default_http2_keep_alive_interval\")]\n    pub interval: HumanDuration,\n\n    // Set the HTTP/2 KEEP_ALIVE_TIMEOUT. This is the time to wait for an ACK\n    // after sending a keepalive ping. If the server doesn't respond within\n    // this time, the connection might be considered dead.\n    // Tonic uses hyper's default (20 seconds) if not set.\n    #[serde(default = \"default_keep_alive_timeout\")]\n    pub timeout: HumanDuration,\n}\n\nimpl GrpcConfig {\n    fn default_max_message_size() -> ByteSize {\n        ByteSize::mib(20)\n    }\n\n    pub fn validate(&self) -> anyhow::Result<()> {\n        ensure!(\n            self.max_message_size >= ByteSize::mb(1),\n            \"max gRPC message size (`grpc.max_message_size`) must be at least 1MB, got `{}`\",\n            self.max_message_size\n        );\n        if let Some(tls_config) = &self.tls_config {\n            tls_config.validate()?;\n        }\n        ensure!(\n            !(self.max_connection_age_grace.is_some() && self.max_connection_age.is_none()),\n            \"`grpc.max_connection_age_grace` requires `grpc.max_connection_age` to be set\"\n        );\n        Ok(())\n    }\n}\n\nimpl Default for GrpcConfig {\n    fn default() -> Self {\n        Self {","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-config/src/node_config/mod.rs#L112-L148","documentation":"GrpcConfig::validate enforces a floor of 1MB on `max_message_size`, since gRPC messages smaller than that would break inter-service communication (Quickwit's internal defaults are 20MB). Values below the floor are rejected with the configured size shown in the message.","triggerScenarios":"Setting `grpc.max_message_size` in the node config to a value below 1MB (e.g. `512KB` or `0`) and starting the node or validating the config.","commonSituations":"Attempting to shrink memory footprint by lowering the gRPC buffer too aggressively; typo'd units (e.g. `1MB` written as `1KB`); copying a config from another project with smaller limits.","solutions":["Set `grpc.max_message_size` to at least `1MB` — the default `20MB` is recommended.","Use correct ByteSize units: `20MB`, `50MB`, etc.; confirm no unit typo dropped the value below the floor.","Do not set it to 0 or omit-with-zero: rely on the default by removing the key entirely if you want stock behavior."],"exampleFix":"# before\ngrpc:\n  max_message_size: 512KB\n# after\ngrpc:\n  max_message_size: 20MB","handlingStrategy":"validation","validationCode":"const min = 1024 * 1024; // 1MB\nconst toBytes = (s) => { /* parse '20MB' style strings */ };\nif (toBytes(cfg.grpc?.max_message_size ?? '20MB') < min) {\n  throw new Error('grpc.max_message_size must be at least 1MB');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never configure grpc.max_message_size below 1MB; use the 20MB default unless you have measured needs.","Double-check byte-size units in YAML (KB vs MB) — typos easily land below the floor.","Remove the key to inherit the default instead of guessing a minimum value."],"tags":["config","grpc","validation","limits"],"backgroundTag":"value-out-of-range","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}