nautechsystems/nautilus_trader · error

Cap'n Proto encoding is not supported for Redis cache…

Error message

Cap'n Proto encoding is not supported for Redis cache payloads

What it means

serialize_payload in the Redis query/cache layer only implements MsgPack and Json serialization. Cap'n Proto is a recognized SerializationEncoding enum value but has no implementation in this code path, so the function bails immediately to prevent silently writing data in an unsupported format.

Solutions

  1. Configure the Redis cache with SerializationEncoding::Json or MsgPack instead of Capnp.
  2. Decouple the Redis client's serialization setting from Capnp-configured components.
  3. If Capnp support is required, add the Capnp arm to serialize_payload in crates/infrastructure/src/redis/queries.rs.
  4. Fail fast at construction time by validating that the configured encoding is Json or MsgPack.

Example fix

// before
let settings = SerializationSettings { encoding: SerializationEncoding::Capnp, .. };
// after
let settings = SerializationSettings { encoding: SerializationEncoding::Json, .. };
Defensive patterns

Strategy: validation

Validate before calling

fn capnp_allowed_for_redis(e: SerializationEncoding) -> bool {
    matches!(e, SerializationEncoding::MsgPack | SerializationEncoding::Json) // Capnp not implemented
}
assert!(capnp_allowed_for_redis(settings.encoding));

Type guard

fn cache_encodings() -> [SerializationEncoding; 2] {
    [SerializationEncoding::MsgPack, SerializationEncoding::Json]
}

Try / catch

match serialize_payload(&payload, &settings) {
    Ok(bytes) => { /* store */ }
    Err(e) if e.to_string().contains("Cap'n Proto") => {
        tracing::error!("Redis cache does not support Capnp; reconfigure to Json/MsgPack");
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling serialize_payload (or the Redis cache/query API accepting a SerializationSetting) with SerializationEncoding::Capnp — e.g. a RedisCacheDatabase configured with Capnp serialization.

Common situations: Sharing one serialization setting across integrations where Capnp is supported elsewhere but not in the Redis cache; misconfigured cache clients copied from other backends; assuming enum completeness means all encodings are implemented.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/aa53aedadc02075a. Report an issue: GitHub.

Appendix: source

Thrown at crates/infrastructure/src/redis/queries.rs:99

    ) -> anyhow::Result<Vec<u8>> {
        match encoding {
            SerializationEncoding::MsgPack => {
                let mut value = serde_json::to_value(payload)?;
                convert_timestamps(&mut value);
                rmp_serde::to_vec(&value)
                    .map_err(|e| anyhow::anyhow!("Failed to serialize msgpack `payload`: {e}"))
            }
            SerializationEncoding::Json => {
                let mut value = serde_json::to_value(payload)?;
                convert_timestamps(&mut value);
                serde_json::to_vec(&value)
                    .map_err(|e| anyhow::anyhow!("Failed to serialize json `payload`: {e}"))
            }
            SerializationEncoding::Sbe => {
                anyhow::bail!("SBE encoding is not supported for Redis cache payloads")
            }
            SerializationEncoding::Capnp => {
                anyhow::bail!("Cap'n Proto encoding is not supported for Redis cache payloads")
            }
        }
    }

    /// Deserializes the given byte slice `payload` into type `T` using the specified `encoding`.
    ///
    /// # Errors
    ///
    /// Returns an error if deserialization from the chosen encoding fails or converting to the target type fails.
    pub fn deserialize_payload<T: DeserializeOwned>(
        encoding: SerializationEncoding,
        payload: &[u8],
    ) -> anyhow::Result<T> {
        let mut value = match encoding {
            SerializationEncoding::MsgPack => rmp_serde::from_slice(payload)
                .map_err(|e| anyhow::anyhow!("Failed to deserialize msgpack `payload`: {e}"))?,
            SerializationEncoding::Json => serde_json::from_slice(payload)
                .map_err(|e| anyhow::anyhow!("Failed to deserialize json `payload`: {e}"))?,

View on GitHub (pinned to 18893faf8b)