nautechsystems/nautilus_trader · error
Failed to serialize SignDoc: {e}
Error message
Failed to serialize SignDoc: {e} What it means
Signing failure in the dYdX credential's sign: serializing the SignDoc to the canonical bytes to be signed failed, so no signature could be produced; the serialization error is embedded in the message.
Source
Thrown at crates/adapters/dydx/src/common/credential.rs:199
/// Returns an error if the address cannot be parsed as a valid account ID.
pub fn account_id(&self) -> anyhow::Result<AccountId> {
self.address
.parse()
.map_err(|e| anyhow::anyhow!("Failed to parse account ID: {e}"))
}
/// Signs a transaction SignDoc.
///
/// This produces the signature bytes that will be included in the transaction.
///
/// # Errors
///
/// Returns an error if SignDoc serialization or signing fails.
pub fn sign(&self, sign_doc: &SignDoc) -> anyhow::Result<Vec<u8>> {
let sign_bytes = sign_doc
.clone()
.into_bytes()
.map_err(|e| anyhow::anyhow!("Failed to serialize SignDoc: {e}"))?;
let signature = self
.signing_key
.sign(&sign_bytes)
.map_err(|e| anyhow::anyhow!("Failed to sign: {e}"))?;
Ok(signature.to_bytes().to_vec())
}
/// Signs raw message bytes.
///
/// Used for custom signing operations outside of standard transaction flow.
///
/// # Errors
///
/// Returns an error if signing fails.
pub fn sign_bytes(&self, message: &[u8]) -> anyhow::Result<Vec<u8>> {
let signature = self
.signing_keyView on GitHub (pinned to 18893faf8b)
Solutions
- Verify the SignDoc fields (chain_id, account_number, account_sequence, messages) are populated and valid before signing
- Build SignDoc through the library's tx-building helpers rather than hand-assembling fields
- Check dydx proto dependency versions for schema compatibility
Example fix
// before
let sign_doc = SignDoc { /* partially filled */ };
let sig = creds.sign(&sign_doc)?;
// after
let sign_doc = SignDocBuilder::new()
.chain_id("dydx-mainnet-1")
.account_number(acct)
.account_sequence(seq)
.messages(vec![msg])
.build()?;
let sig = creds.sign(&sign_doc)?; Defensive patterns
Strategy: validation
Validate before calling
assert!(!sign_doc.chain_id.is_empty(), "chain_id required"); assert!(!sign_doc.messages.is_empty(), "at least one message required");
Try / catch
let sig = creds.sign(&sign_doc).map_err(|e| { eprintln!("SignDoc serialization failed — verify chain_id, account_number and messages"); e })?; Prevention
- Build SignDoc via the library's builder/helpers instead of hand-assembly
- Populate chain_id, account_number, and account_sequence before signing
- Keep dydx proto crate versions in sync across the workspace
When it happens
Trigger: Calling sign(&SignDoc) where the SignDoc cannot be encoded — e.g. a SignDoc built with malformed/empty fields that the protobuf encoder rejects, or a messages/body combination that fails encoding.
Common situations: Constructing SignDoc manually with missing account number, chain-id, or malformed tx messages; protobuf schema mismatch after upgrading the dydx proto crate.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Signer private key in '{}' is not a valid secp256k1 private
- Invalid secp256k1 private key: {e}
- Failed to derive account ID: {e}
- Failed to parse account ID: {e}
- Failed to sign: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5b63b34382f1ac8d.
Report an issue: GitHub.