Aggregator returns -2 "Failed to decode signed transaction", yet local simulation succeeds

I’m building a Solana trading bot using Jupiter’s Ultra API and v1 endpoints. I request a versioned transaction from /ultra/v1/order, deserialize with VersionedTransaction.deserialize(...), sign with my private key (64 bytes), then re-serialize and post to /ultra/v1/execute.

Issue: The aggregator always responds with code -2, "Failed to decode signed transaction", even though my local simulation (using simulateTransaction) shows err: null and the logs confirm it’s fully valid on-chain.

Setup Details

  • I have a Phantom wallet. I exported the private key to a base58 string (64 bytes).
  • My environment: SOLANA_RPC_URL = https://api.mainnet-beta.solana.com
  • I am swapping USDC (EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v) to WETH (7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs).
  • No delays in signing; I receive the transaction from /order, sign, then immediately call /execute.

Logs

  1. simulateTransaction results in err: null and a normal set of logs (no blockhash or signature errors). So Solana itself can decode the signed transaction just fine.
  2. Right after, I post signedTransaction + requestId to POST /ultra/v1/execute:
{
  "signedTransaction": "<base64>",
  "requestId": "23364544d-f5d8-480r-ae56-df34763dsd4"
}
  1. Jupiter responds:
{
  "code": -2,
  "error": "Failed to decode signed transaction"
}

Request ID & Transaction

  • Request ID: 23364544d-f5d8-480r-ae56-df34763dsd4
  • The aggregator itself calls it an “invalid signed transaction,” but local simulation shows it’s valid on-chain.

Questions

  1. Partial Signing? Does the aggregator require an internal ephemeral signature that I might accidentally overwrite? If so, how do I preserve aggregator signatures while adding mine?
  2. Known Bug? Are there any known issues or route restrictions that return -2 despite a valid versioned transaction?
  3. Seed vs Full 64-Byte Key? I’m using a 64-byte secret key from Phantom’s “Export Private Key.” Could that cause aggregator decoding issues?

Thank you! Please let me know if there’s something special needed to avoid -2 from the aggregator. Any guidance or known workarounds are greatly appreciated.

2 Likes

Fixed, I was doing it wrong, leaving it here for reference:

vtx.serialize().toString('base64')

It should be:

Buffer.from(vtx.serialize()).toString('base64')
1 Like

you can join the discord channel and go to the dev section in the future. People will support you over there

3 Likes

Thanks.

I like forums, it serves as a reference for future people having similar questions. It may help the amazing Jupiter product grow even more.

It also helps LLMs train themselves to avoid making stupid mistakes.

2 Likes