DEV Community

Cover image for Agave 4.2: Transaction V1 Breaking Changes Checklist
OrbitFlare RPC
OrbitFlare RPC

Posted on

Agave 4.2: Transaction V1 Breaking Changes Checklist

Cover Image

Transaction V1 activates on Solana mainnet on 10 September 2026, at the next epoch boundary. It raises the maximum transaction size from 1,232 bytes to 4,096 bytes, and it uses a new format that older client libraries cannot read.

Only one item on this list throws an error. The rest let your code keep running while it reports the wrong numbers.

Where each change stands

Change SIMD Status
Transaction V1 and the 4,096 byte limit 0296 and 0385 Activates at the end of epoch 1031, 10 September 2026
Rent reduction, step one of five 0437 Live on mainnet since 3 September 2026
Slot times, 400ms to 350ms 0525 Live since epoch 1020, 21 August 2026
Slot times, 350ms to 300ms 0525 Live since epoch 1024, 28 August 2026
Slot times, 300ms to 250ms 0525 Pending on mainnet, live on testnet
Alpenglow consensus 0326 Turns on with Agave 4.3

Agave 4.2 came out on 11 August 2026, but nothing in it switched on that day. Each change has its own feature gate and turns on when the cluster activates it, which is why the dates above are all different.

1. Ask for v1 on every call that returns transactions

What breaks. Any call that returns transactions and has not said it can handle version 1.

How it fails. With an error, and this is the only item that does. You get error code -32015. The whole call fails, not just the one transaction, so a single v1 transaction anywhere in a block breaks getBlock for that entire block.

Where to check. getBlock, getTransaction, getTransactionsForAddress when transactionDetails is full, and the transactionSubscribe and blockSubscribe WebSocket subscriptions.

What to do. Set maxSupportedTransactionVersion: 1 on all of them. Update your SDK first and check that it can actually read v1, because asking for a version your client cannot parse just moves the error somewhere else. For TypeScript you need @solana/kit 8.0 or later, or @solana/web3.js v3. For Rust, solana-rpc-client-api 4.2 or later.

2. Read the priority fee from the header

What breaks. Anything that works out fees by looking for a ComputeBudget instruction.

How it fails. With no error at all. A v1 transaction does not have a ComputeBudget instruction. Code that goes looking for one finds nothing, records a zero, and carries on. Every v1 transaction shows up as paying no priority fee.

Why it moved. Under v0, a validator had to read instruction data before it knew what a transaction was bidding, which slowed things down. In v1 the compute budget sits in the transaction header instead, holding the priority fee, the compute unit limit, the account data size limit and the heap request. If a v1 transaction does include a ComputeBudget instruction, it is ignored.

What to do. Read priorityFee from the transactionConfig object. Watch the units, because this catches people out. In legacy and v0 the number was a price in micro-lamports per compute unit. In v1 it is a total in lamports. So a priorityFee of 50000 means 50,000 lamports for the whole transaction.

3. Stop expecting an update from every writable account

What breaks. Matching transactions to accounts, reconciliation, and anything that counts account updates.

How it fails. With no error. Agave 4.2 no longer writes accounts that a transaction locked for writing but did not change, so those accounts stop sending updates in getBlock responses and in gRPC and WebSocket streams. Providers running the release are seeing around 80 percent fewer events, though how much you lose depends on what you are watching.

What to do. Treat a missing update as "this account did not change" rather than as something going wrong. The fee payer is the only account you can count on, because it always changes. Then look at your monitoring, because anything that alerts on how many updates you receive will see a big drop that has nothing to do with your service being broken.

4. Add the new reward type

What breaks. Parsers that only accept a fixed list of reward types.

How it fails. With no error. Stake accounts that are being deactivated now get a final payout marked DeactivatedStake, and it shows up in getBlock and blockSubscribe rewards next to the fee, rent, staking and voting types you already handle. A parser that does not know the new value throws the record away.

What to do. Add DeactivatedStake to the list you accept. While you are there, make the fallback log anything it does not recognise instead of dropping it, so the next new value shows up in your logs rather than as a hole in your numbers.

5. Update your Token-2022 parsing

What breaks. Anything reading Token-2022 instructions or mint extensions from jsonParsed responses.

How it fails. Fields you expect are gone, and fields you did not expect now have data in them.

What changed.

  • depositConfidentialTransfer and withdrawConfidentialTransfer no longer have source and destination. There is one account field instead, because the two were always the same account anyway.
  • unwrapLamports, confidentialBurn, permissioned burn and the batch operations now come back as parsed JSON instead of raw bytes. On unwrapLamports the amount is a string, and it is left out entirely when the whole balance is being unwrapped.
  • Mints with extensions the parser did not recognise used to come back with an empty extensions array. Now you get the real list, so code that read an empty array as "this mint has no extensions" was already wrong and will now see names it does not know.

What to do. Handle the account field, do not throw on extension names you do not recognise, and treat a missing amount on unwrapLamports as a full unwrap rather than a zero.

6. Get rid of hardcoded slot times

What breaks. Any timing logic with 400ms written into it.

How it fails. Slowly. Timeouts fire too early, estimates of how many blocks fit in a window drift, and anything turning a slot count into a real duration is already wrong today.

What to do. Mainnet went to 350ms at epoch 1020 on 21 August 2026 and to 300ms at epoch 1024 on 28 August, and SIMD-0525 keeps stepping it down 50ms at a time towards 200ms. The 250ms gate is already live on testnet. The network holds at each step if too many blocks are being skipped. Do not use the SDK constant either, because it has not kept up with mainnet. Work your timing out from block timestamps, or put the value in config so the next step down is a config change and not a release.

Versions to pin

The minimum column is the first version that can read v1.

Component Minimum for v1 Latest (2026-09-10)
solana-message 4.1.1 4.6.0
solana-transaction 4.1.6 4.3.0
solana-transaction-status 4.1.2 4.2.2
yellowstone-grpc-proto 12.6.0 12.7.0
yellowstone-grpc-client 13.4.0 13.5.0
OrbitFlare proto crate, orbitflare-sdk-proto 0.1.2 0.1.2
OrbitFlare Rust SDK, orbitflare-sdk 0.3.1 0.3.1
OrbitFlare TypeScript SDK, @orbitflare/sdk 0.3.1 0.3.1
OrbitFlare Go SDK, orbitflare-sdk-go v0.1.1 v0.1.1

orbitflare-sdk-proto is an internal dependency of the Rust SDK and is pulled in automatically; you only need to pin it directly if you consume the protos yourself.

If you are on Go, regenerate your protobuf bindings from the current Yellowstone protos and solana-storage-proto instead of using a generated file you pinned a while ago.

If you decode transactions yourself

If you parse raw transaction bytes, whether through our decode example, your own shred decoder, or something you wrote by hand, three things about the layout have changed:

  • The version byte is 129. That is how you tell a v1 transaction from legacy and v0.
  • The signatures are at the end of the transaction, not the start.
  • The compute budget is in the header, not in an instruction.

Address lookup tables do not exist in v1. That is fine in practice, because with 4,096 bytes you have room to list the accounts directly instead of pointing at a table.

FAQ

Do I have to start sending v1 transactions?

No. Legacy and v0 transactions keep working exactly as before. What you cannot avoid is reading v1, because other people will send them and they will land in the blocks you fetch. That is why item one is about maxSupportedTransactionVersion and not about building v1 transactions yourself.

What happens if I do not set maxSupportedTransactionVersion to 1?

Any getBlock, getTransaction or subscription response that contains even one v1 transaction fails with error code -32015. The whole call fails, not the one transaction. Once v1 is active, that means most blocks.

Why does my fee dashboard show some transactions paying zero?

Those are v1 transactions. They carry no ComputeBudget instruction, so code that scans instructions for the fee finds nothing. Read priorityFee from transactionConfig instead, and note it is a total in lamports rather than a per-compute-unit price.

Why did my account update volume drop after upgrading?

Agave 4.2 stopped writing accounts that a transaction locked but did not change, so they no longer send updates. Nothing is wrong. Treat a missing update as "unchanged". The fee payer is the only account that always sends one.

What is the slot time on mainnet right now?

300ms, since epoch 1024 on 28 August 2026. It was 400ms until 21 August and 350ms for the week in between. The next step to 250ms is live on testnet and pending on mainnet. Do not hardcode any of these.

Does this change anything on OrbitFlare's side?

The RPC, Yellowstone gRPC and Jetstream endpoints all run the current Agave release, so v1 transactions come through without any change to your subscription or endpoint. The update is in the client library that reads them, which is what the versions table above is for.

Conclusion

Six things to check, and only the first one will tell you it is broken. The other five will let your service run normally while the numbers it produces go quietly wrong.

Do them in order. Fix the read calls first, since that is where the real error is, then the fee reading, then the account and reward parsing, then the timing constants.

OrbitFlare's RPC plans, Yellowstone gRPC and Jetstream all run the current Agave release in every region, so the format change is handled on our side. Jetstream sends v1 transactions without you changing anything about your subscription. The part you need to update is the client that reads it.

Resources

  1. SIMD-0296: larger transactions
  2. SIMD-0385: transaction v1
  3. Agave 4.2 release overview (Solana)
  4. Reduced slot times (SIMD-0525)
  5. Reduced rent (SIMD-0437)

Top comments (0)