linera-io/linera-protocol · error · anyhow

The only allowed protocol is tcp

Error message

The only allowed protocol is tcp

What it means

Raised while parsing a `dualrocksdbscylladb:` storage configuration in `StorageConfig::from_str` (linera-storage-runtime). The third segment (after directory and spawn mode) must be the literal `tcp` — the dual backend only supports plain TCP connections to ScyllaDB; any other scheme is rejected.

Source

Thrown at linera-storage-runtime/src/storage_config.rs:247

                    "For DualRocksDbScyllaDb, the formatting has to be dualrocksdbscylladb:directory:mode:tcp:hostname:port:namespace"
                );
            }
            let path = Path::new(parts[0]);
            let path = path.to_path_buf();
            let path_with_guard = PathWithGuard::new(path);
            let spawn_mode_name = parts
                .get(1)
                .copied()
                .expect("validated by the parts length check above");
            let spawn_mode = match spawn_mode_name {
                "spawn_blocking" => Ok(RocksDbSpawnMode::SpawnBlocking),
                "block_in_place" => Ok(RocksDbSpawnMode::BlockInPlace),
                "runtime" => Ok(RocksDbSpawnMode::get_spawn_mode_from_runtime()),
                _ => Err(anyhow!("Failed to parse {spawn_mode_name} as a spawn_mode",)),
            }?;
            let protocol = parts[2];
            if protocol != "tcp" {
                bail!("The only allowed protocol is tcp");
            }
            let address = parts[3];
            let port_str = parts[4];
            let port = NonZeroU16::from_str(port_str)
                .map_err(|_| anyhow!("Failed to find parse port {port_str} for {s}"))?;
            let uri = format!("{address}:{port}");
            let inner_storage_config = InnerStorageConfig::DualRocksDbScyllaDb {
                path_with_guard,
                spawn_mode,
                uri,
            };
            let namespace = if parts.len() == 5 {
                DEFAULT_NAMESPACE.to_string()
            } else {
                parts[5].to_string()
            };
            return Ok(StorageConfig {
                inner_storage_config,

View on GitHub (pinned to 6c226ddcb3)

Solutions

  1. Set the transport segment to `tcp`: `dualrocksdbscylladb:<dir>:<mode>:tcp:<host>:<port>[:<ns>]`
  2. Confirm ScyllaDB's native CQL transport (TCP) address is what you mean — not the HTTP JMX/management port

Example fix

# before
--storage dualrocksdbscylladb:/db:block_in_place:http:host:9042:table_ns

# after
--storage dualrocksdbscylladb:/db:block_in_place:tcp:host:9042:table_ns
Defensive patterns

Strategy: validation

Validate before calling

// Rust: check the dual-config transport segment before FromStr
if let Some(rest) = storage_str.strip_prefix("dualrocksdbscylladb:") {
    let protocol = rest.split(':').nth(2);
    anyhow::ensure!(
        protocol == Some("tcp"),
        "dualrocksdbscylladb transport must be tcp, got {protocol:?}"
    );
}

Prevention

When it happens

Trigger: Passing `dualrocksdbscylladb:/db:block_in_place:http:host:9042:ns` or any transport segment other than `tcp`.

Common situations: Substituting the ScyllaDB URI scheme from other tooling (http/cql/tls) into the Linera config string.

Related errors


AI-assisted analysis of linera-io/linera-protocol@6c226ddcb3 (2026-08-22). Data as JSON: /api/errors/966e8b5856589d64. Report an issue: GitHub.