Safe Multisig Error GS026: Invalid Owner Provided Signer Fix
Safe multisig error GS026 "Invalid owner provided" occurs during execTransaction when one of the recovered signature addresses is not an authorized owner of the Safe, or when multiple signatures are not sorted in strictly ascending numerical order. Safe contracts enforce lexicographical address sorting (owner1 < owner2) to eliminate duplicate signature replay. Sort all owner signatures by address before submitting, and verify active owners on-chain using the getOwners call.
# Root Cause & Technical Architecture
Inside `GnosisSafe.checkSignatures()`, the contract loops through the concatenated 65-byte signature bytes and recovers signer addresses using `ecrecover`. To guarantee uniqueness without quadratic gas loops, Safe enforces: `require(currentOwner > lastOwner && isOwner(currentOwner), "GS026")`. If two signatures are out of order, if an address appears twice, or if a signer was recently removed from the Safe, the assertion fails with `GS026`.
# 4-Step Actionable Diagnostic Protocol
Step-by-Step ResolutionSort Owner Signatures by Address in Ascending Order
Order signatures numerically: address(signer1) < address(signer2). Concatenating signatures in arbitrary order guarantees a GS026 revert.
Verify Active Safe Ownership on Target Network
Call safe.getOwners() on-chain to verify that every private key that signed the transaction is currently registered as an active owner.
Check v-Value Normalization for EIP-712 Signatures
Ensure the recovery identifier byte (v) is properly normalized to 27 or 28 (or 31/32 for eth_sign ledger mode) per Safe specifications.
Audit Threshold Configuration Against Signature Count
Confirm that the total number of provided valid owner signatures meets or exceeds safe.getThreshold().
# Diagnostic Verification Code / Command
typescript// Sort Safe signatures in strictly ascending order of signer address
interface OwnerSignature {
signer: `0x${string}`;
data: string; // 65-byte hex signature (r + s + v)
}
function packSortedSignatures(signatures: OwnerSignature[]): string {
// Sort numerically ascending (GS026 prevention rule: currentOwner > lastOwner)
const sorted = [...signatures].sort((a, b) =>
BigInt(a.signer) < BigInt(b.signer) ? -1 : 1
);
// Concatenate sorted signature hex strings
return '0x' + sorted.map(s => s.data.replace('0x', '')).join('');
} Launch ERC-4337 UserOp Decoder
Execute client-side cryptographic simulation and parameter checks safely in your browser via native WebCrypto without sending private keys or mnemonics over the wire.
Read Full Investigation & Recovery Workflow
Explore complete architectural diagrams, edge-case failure trees, and detailed post-mortem analysis in our verified deep guide.
# Related Diagnostic Codes in ERC-4337 & Safe
Related Hex StatusesERC-4337 Error AA10: Sender Already Constructed UserOp Fix
Fix ERC-4337 error AA10 sender already constructed. Resolve non-empty initCode sent for deployed smart accounts, bundler estimation, and counterfactuals.
ERC-4337 Error AA20: Account Not Deployed EntryPoint Revert
Fix ERC-4337 error AA20 account not deployed. Troubleshoot empty initCode for counterfactual smart accounts, factory calldata, and pre-deployment.
ERC-4337 Error AA24: Signature Error UserOp Validation Fix
Fix ERC-4337 error AA24 signature error. Resolve validateUserOp signature mismatch, userOpHash EIP-712 hashing errors, and signature aggregator faults.
# Frequently Asked Questions
FAQ SchemaWhy does Safe require signatures to be sorted by address?
Sorting by address allows the Safe smart contract to verify in a single O(N) loop that all signers are unique and valid without duplicate signature exploits.
Can I reuse an old signature if owner ordering is maintained?
No. Safe incorporates a monotonic nonce into the transaction hash, so signatures cannot be replayed for subsequent transactions.
Does GS026 occur if an owner was removed after signing?
Yes. If a signer was an owner when they signed off-chain but was removed on-chain before the transaction was broadcast, GS026 will be thrown.