in-solana by Supanode

InvalidWritableAccount

A transaction marks an account as writable, but the runtime determined that this account must be read-only for this instruction.

Common causes

  1. System-owned executable account marked writable. Program accounts (executables) and native program accounts like the System Program, Token Program, or Clock sysvar cannot be marked writable.
  2. Wrong isSigner or isWritable flags. The instruction’s account meta has isWritable: true for an account that the program expects to be read-only.
  3. Sysvar passed as writable. Sysvars like Clock, Rent, and StakeHistory are always read-only.

How to fix

  1. Check account meta flags. Review your instruction builder and ensure read-only accounts have isWritable: false:
{
  pubkey: systemProgram,
  isSigner: false,
  isWritable: false,  // programs are never writable
}
  1. Never mark program IDs as writable. Any program account passed in the instruction’s programId field or as an invoked program is always read-only.
  2. Check sysvar usage. Sysvars should always be read-only. If your program needs sysvar data, it can read it without the account being writable.

Accounts that are always read-only

  • All executable program accounts
  • Native programs (System, Token, Associated Token, Compute Budget)
  • All sysvars (Clock, Rent, Fees, SlotHashes, StakeHistory, etc.)
  • Accounts loaded through Address Lookup Tables with the read-only table section

FAQ

What happens if I mark a read-only account as writable? The transaction is rejected before execution. No fees are charged because the transaction fails pre-processing validation.

Does this affect CPI calls? Yes. If a program makes a CPI (Cross-Program Invocation) and passes an account as writable that was marked read-only in the outer instruction, the CPI will fail with this error.

Error text variants

  • InvalidWritableAccount
  • invalid writable account
  • cannot write to read-only account

Updated: