linera-io/linera-protocol · error
Proxy URI should be valid
Error message
Proxy URI should be valid
What it means
forward_notifications (linera-rpc/src/grpc/server.rs:513) builds a tonic Channel from the configured proxy address string with Channel::from_shared(...).expect("Proxy URI should be valid"). from_shared fails when the string is not a valid http/https URI - missing scheme (bare host:port), whitespace, invalid characters, or unsupported scheme. The panic kills the notification-forwarding task on the validator, so notifications stop flowing to the proxy.
Source
Thrown at linera-rpc/src/grpc/server.rs:521
Ok(())
});
GrpcServerHandle { handle }
}
/// Continuously waits for receiver to receive notifications and sends them to
/// the proxy in batches for improved throughput.
#[instrument(skip(receiver, config))]
async fn forward_notifications(
nickname: String,
proxy_address: String,
exporter_addresses: Vec<String>,
mut receiver: tokio::sync::broadcast::Receiver<Notification>,
config: NotificationConfig,
) {
let channel = tonic::transport::Channel::from_shared(proxy_address.clone())
.expect("Proxy URI should be valid")
.connect_lazy();
let client = NotifierServiceClient::new(channel)
.max_encoding_message_size(GRPC_MAX_MESSAGE_SIZE)
.max_decoding_message_size(GRPC_MAX_MESSAGE_SIZE);
let exporter_clients: Vec<NotifierServiceClient<Channel>> = exporter_addresses
.iter()
.map(|address| {
let channel = tonic::transport::Channel::from_shared(address.clone())
.expect("Exporter URI should be valid")
.connect_lazy();
NotifierServiceClient::new(channel)
.max_encoding_message_size(GRPC_MAX_MESSAGE_SIZE)
.max_decoding_message_size(GRPC_MAX_MESSAGE_SIZE)
})
.collect::<Vec<_>>();
let mut forwarder = BatchForwarder {View on GitHub (pinned to 6c226ddcb3)
Solutions
- Write the full URI including scheme: 'http://<host>:<port>' in the proxy notification address.
- Validate the address before startup: `tonic::transport::Uri::try_from(addr)` or a quick URL parse check.
- Trim whitespace and remove quotes/artifacts from templated config values.
- Check the validator config docs for the notification section of your version to confirm the expected format.
Example fix
# before (validator config, internal proxy notification) proxy_address = "10.0.0.1:9123" # Channel::from_shared panics: invalid URI # after proxy_address = "http://10.0.0.1:9123"
Defensive patterns
Strategy: validation
Validate before calling
// Validate all notification URIs at config load, before the server starts:
fn validate_grpc_uri(uri: &str) -> anyhow::Result<()> {
let parsed = uri.parse::<tonic::transport::Uri>()
.map_err(|e| anyhow::anyhow!("invalid proxy URI '{uri}': {e}"))?;
anyhow::ensure!(matches!(parsed.scheme(), Some(s) if s == &http::uri::Scheme::HTTP || s == &http::uri::Scheme::HTTPS),
"URI '{uri}' must include an http:// or https:// scheme");
Ok(())
}
validate_grpc_uri(&config.proxy_address)?; Type guard
fn is_valid_http_uri(s: &str) -> bool {
s.parse::<tonic::transport::Uri>().map(|u| u.scheme().is_some()).unwrap_or(false)
} Prevention
- Always write notification addresses as 'http://host:port' in validator configs.
- Add a config-lint step to deployment that URI-parses every proxy/exporter address.
- Avoid templating addresses from unvalidated environment variables.
When it happens
Trigger: Configuring a validator's internal proxy notification address as a bare 'host:port' (e.g. '10.0.0.1:9123') instead of 'http://10.0.0.1:9123', or including whitespace/copy-paste artifacts in the address from the validator config file.
Common situations: Hand-writing validator TOML with internal/proxy notification sections; addresses copied from other config styles (socks://, grpc://, or no scheme); config templating that injects stray characters.
Related errors
- Exporter URI should be valid
- invalid block export configuration: {message}
- MissingCertificates
- InconsistentChainId
- a running notification server
AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22).
Data as JSON: /api/errors/3ec1c6c17ca2535c.
Report an issue: GitHub.