{"record":{"id":"7fed2cd55b5aa3e5","repo":"linera-io/linera-protocol","slug":"network-protocol-mismatch-cannot-have-internal-p","errorCode":null,"errorMessage":"network protocol mismatch: cannot have {internal_protocol} and {external_protocol} ","messagePattern":"network protocol mismatch: cannot have (.+?) and (.+?) ","errorType":"validation","errorClass":"anyhow","httpStatus":null,"severity":"critical","filePath":"linera-service/src/proxy/main.rs","lineNumber":214,"sourceCode":"            (\n                NetworkProtocol::Simple(internal_transport),\n                NetworkProtocol::Simple(public_transport),\n            ) => Self::Simple(Box::new(SimpleProxy {\n                internal_config: context\n                    .config\n                    .internal_network\n                    .clone_with_protocol(internal_transport),\n                public_config: context\n                    .config\n                    .validator\n                    .network\n                    .clone_with_protocol(public_transport),\n                send_timeout: context.send_timeout,\n                recv_timeout: context.recv_timeout,\n                storage,\n                id: context.id,\n            })),\n            _ => bail!(\"network protocol mismatch: cannot have {internal_protocol} and {external_protocol} \"),\n        };\n\n        Ok(proxy)\n    }\n}\n\n#[derive(Debug, Clone)]\npub struct SimpleProxy<S>\nwhere\n    S: Storage + Clone + Send + Sync + 'static,\n{\n    public_config: ValidatorPublicNetworkPreConfig<TransportProtocol>,\n    internal_config: ValidatorInternalNetworkPreConfig<TransportProtocol>,\n    send_timeout: Duration,\n    recv_timeout: Duration,\n    storage: S,\n    id: usize,\n}","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/linera-io/linera-protocol/blob/6c226ddcb332ef55118dc8d0aafbd093d5420899/linera-service/src/proxy/main.rs#L196-L232","documentation":"Raised in `Proxy::from_context` (linera-service proxy) at startup when the validator configuration mixes protocol families: `config.internal_network.protocol` and `config.validator.network.protocol` must both be `Grpc` or both be `Simple`. Any mixed combination (Grpc internal + Simple external, or Simple internal + Grpc/TLS external) hits the catch-all `bail!` and the proxy process refuses to start. The proxy cannot translate between the gRPC and Simple (TCP/UDP) network stacks, so the configuration is rejected rather than partially run.","triggerScenarios":"Running `linera proxy` with a config where `internal_network.protocol` is set to `grpc` while `validator.network.protocol` remains `simple` (or the reverse); hand-editing a generated validator config to change only one side; mixing config fragments produced by different linera-configgen versions.","commonSituations":"Migrating a validator deployment from Simple to gRPC networking and editing only the internal section; manually assembling config.toml for a proxy shard; copy-pasting network sections between validator configs with different generations.","solutions":["Edit the validator config so both `internal_network.protocol` and `validator.network.protocol` use the same family (both `grpc` or both `simple`)","Regenerate the whole config with `linera configgen` (or the config-generation command used originally) instead of hand-editing one section","Diff the config against a known-good config from the same linera version","Verify each shard's config in a multi-shard setup — one mismatched shard fails the proxy startup"],"exampleFix":"# before (config.toml)\n[internal_network]\nprotocol = { type = \"grpc\", tls = \"cleartext\" }\n[validator.network]\nprotocol = { type = \"simple\", transport = \"tcp\" }\n\n# after\n[internal_network]\nprotocol = { type = \"grpc\", tls = \"cleartext\" }\n[validator.network]\nprotocol = { type = \"grpc\", tls = \"cleartext\" }","handlingStrategy":"validation","validationCode":"// Rust: validate the proxy config before constructing/running the proxy\nuse linera_base::network::NetworkProtocol;\n\nfn protocols_same_family(internal: &NetworkProtocol, external: &NetworkProtocol) -> bool {\n    matches!((internal, external),\n        (NetworkProtocol::Grpc { .. }, NetworkProtocol::Grpc(_))\n        | (NetworkProtocol::Simple(_), NetworkProtocol::Simple(_)))\n}\n\nanyhow::ensure!(\n    protocols_same_family(&config.internal_network.protocol, &config.validator.network.protocol),\n    \"internal and external protocols must both be grpc or both be simple\"\n);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never edit only one of internal_network/validator.network — change both together","Generate validator configs with linera-configgen rather than hand-editing","Add a config lint step in deployment scripts that asserts both protocol families match","Keep per-shard configs in sync; a single mismatched shard aborts the proxy"],"tags":["config","proxy","network","grpc","linera-validator"],"backgroundTag":"config-protocol-mismatch","analyzedSha":"6c226ddcb332ef55118dc8d0aafbd093d5420899","analyzedAt":"2026-08-22T22:49:09.787Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}