{"id":3863,"date":"2026-10-08T11:29:23","date_gmt":"2026-10-08T11:29:23","guid":{"rendered":"https:\/\/nownodes.io\/blog\/?p=3863"},"modified":"2026-10-08T11:29:25","modified_gmt":"2026-10-08T11:29:25","slug":"how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction","status":"publish","type":"post","link":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/","title":{"rendered":"How to Sign a Transaction Offline and Broadcast It with eth_sendRawTransaction"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">To sign an Ethereum transaction offline, you build the transaction, sign it locally with your private key, and get back a serialized blob of hex. Then you hand that blob to the network with <code>eth_sendRawTransaction<\/code>, which checks it and drops it into the mempool. The signing and the sending are two separate acts, and the private key only takes part in the first one. It never travels anywhere.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That separation is the whole point. This guide covers why you would sign a transaction this way, what the signed object actually contains, and how to go from a plain-text transaction to a confirmed one using web3.py, ethers.js, or a raw JSON-RPC call.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"why-sign-a-transaction-offline-at-all\">Why Sign a Transaction Offline at All?<\/h2>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-48-1024x683.png\" alt=\"\" class=\"wp-image-3864\" srcset=\"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-48-1024x683.png 1024w, https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-48-300x200.png 300w, https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-48-768x512.png 768w, https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-48.png 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">There are two ways to get a transaction onto Ethereum. The first is <code>eth_sendTransaction<\/code>, where you hand an unsigned transaction to a client that holds your private key, and it signs and submits in one step. The second is to sign the transaction yourself and submit the finished product with <code>eth_sendRawTransaction<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The first method only works when the client controls the key. A local Geth instance with an unlocked account can do it. A hosted endpoint cannot, and will not, because it never has your key in the first place. Send <code>eth_sendTransaction<\/code> or <code>eth_signTransaction<\/code> to most API providers and the call is rejected, since there is nothing on their side to sign with.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So anyone building against a hosted endpoint signs locally by default. There is no other option. But even teams that could unlock an account on their own machine usually avoid it, because keeping a key unlocked on an internet-facing server is a standing liability. Signing locally keeps the key on hardware you control.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Offline signing takes that idea further. You can prepare and sign a transaction on a machine that has never touched the internet, move only the signed hex to a connected machine, and broadcast it there. The key stays air-gapped. This is how hardware wallets and cold-storage setups move funds without ever exposing the secret that controls them.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"what-signing-an-ethereum-transaction-actually-does\">What &#8220;Signing&#8221; an Ethereum Transaction Actually Does<\/h2>\n\n\n<p class=\"wp-block-paragraph\">A signed transaction is the set of transaction fields plus an ECDSA signature that proves the holder of one specific private key authorized those exact fields. Change a single value after signing \u2014 the amount, the recipient, the gas limit \u2014 and the signature no longer matches, so the network rejects it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is why a broadcasting endpoint can refuse to relay your transaction but can&#8217;t tamper with it. It can drop the request, but it cannot bump your gas, redirect your funds, or alter the recipient, because any edit invalidates the signature it would then have to forward.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The signature also pins the transaction to one chain. <a href=\"https:\/\/eips.ethereum.org\/EIPS\/eip-155\" rel=\"nofollow noopener noreferrer\">EIP-155<\/a> folds the chain ID into the signed data, so a transaction signed for Ethereum mainnet (chain ID 1) can&#8217;t be replayed on a testnet or an EVM-compatible chain that uses a different ID. When you sign offline, you are responsible for setting that chain ID correctly, because there is no connected client to fill it in for you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The output of signing is a <em>raw transaction<\/em>: the fields and signature serialized with RLP encoding into a single <code>0x<\/code>-prefixed hex string. That string is self-contained. It carries everything the network needs to verify and execute the transaction, which is exactly why it can be generated on an offline machine and carried anywhere.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Signing is pure computation. It is math over the transaction data and the key, with no call to any server. That is what makes offline signing possible at all.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"what-goes-into-the-transaction-you-sign\">What Goes Into the Transaction You Sign<\/h2>\n\n\n<p class=\"wp-block-paragraph\">Before you can sign anything, you need a complete transaction object. For a standard transfer on today&#8217;s network, that means a type 2 (EIP-1559) transaction with these fields:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Field<\/th><th>What it is<\/th><\/tr><\/thead><tbody><tr><td><code>nonce<\/code><\/td><td>The sender&#8217;s transaction count, so the network orders your transactions and rejects duplicates<\/td><\/tr><tr><td><code>to<\/code><\/td><td>The recipient address, or empty for a contract deployment<\/td><\/tr><tr><td><code>value<\/code><\/td><td>Amount of ETH to send, in wei<\/td><\/tr><tr><td><code>data<\/code><\/td><td>Call data for a contract, or empty for a plain transfer<\/td><\/tr><tr><td><code>gas<\/code> \/ <code>gasLimit<\/code><\/td><td>Maximum gas units the transaction may consume (21,000 for a simple transfer)<\/td><\/tr><tr><td><code>maxFeePerGas<\/code><\/td><td>The most you&#8217;ll pay per gas unit, base fee included<\/td><\/tr><tr><td><code>maxPriorityFeePerGas<\/code><\/td><td>The tip per gas unit that goes to the validator<\/td><\/tr><tr><td><code>chainId<\/code><\/td><td>Which chain the transaction is valid on (1 for Ethereum mainnet)<\/td><\/tr><tr><td><code>type<\/code><\/td><td>The transaction format \u2014 <code>2<\/code> for EIP-1559<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/eips.ethereum.org\/EIPS\/eip-1559\" rel=\"nofollow noopener noreferrer\">EIP-1559<\/a> replaced the single <code>gasPrice<\/code> field with the <code>maxFeePerGas<\/code> and <code>maxPriorityFeePerGas<\/code> pair. The base fee is set by the network and burned; your tip is what incentivizes a validator to include you. Type 2 is the common format for normal transfers now, but it isn&#8217;t the only one. Legacy transactions (type 0) still work and use a flat <code>gasPrice<\/code>. There are also type 1 access-list transactions (EIP-2930), type 3 blob transactions used mostly by Layer 2 rollups (EIP-4844), and, since the Pectra upgrade, type 4 transactions (EIP-7702) that let a regular account temporarily act like a smart contract wallet.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The one field people get wrong is <code>nonce<\/code>. It has to equal the sender&#8217;s current transaction count. Read it from the network with <code>eth_getTransactionCount<\/code> using the <code>\"pending\"<\/code> tag so it includes any transactions you&#8217;ve already sent but that haven&#8217;t been mined yet. Guess it and the network will reject the result.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"how-to-sign-and-broadcast-step-by-step\">How to Sign and Broadcast, Step by Step<\/h2>\n\n\n<p class=\"wp-block-paragraph\">The flow is the same no matter which library you use:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Read the chain data you need.<\/strong> Fetch the current nonce, chain ID, and fee levels. This is the one part that needs a connection.<\/li>\n\n\n\n<li><strong>Build the transaction object<\/strong> with the fields above.<\/li>\n\n\n\n<li><strong>Sign it locally<\/strong> with the private key. No network call happens here.<\/li>\n\n\n\n<li><strong>Take the serialized raw hex<\/strong> the signing step returns.<\/li>\n\n\n\n<li><strong>Broadcast it<\/strong> with <code>eth_sendRawTransaction<\/code>.<\/li>\n\n\n\n<li><strong>Poll for the receipt<\/strong> to confirm it was mined.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Only step 1 and step 5 touch the network, and they can run on a different machine than steps 2 through 4. That gap is where the security benefit lives.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"signing-with-web3py-python\">Signing with web3.py (Python)<\/h3>\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/web3py.readthedocs.io\/en\/stable\/transactions.html\" rel=\"nofollow noopener noreferrer\">web3.py transactions guide<\/a> uses <code>w3.eth.account.sign_transaction<\/code> to sign and <code>send_raw_transaction<\/code> to broadcast:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">python<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import os\nfrom web3 import Web3\n\nw3 = Web3(Web3.HTTPProvider(\"YOUR_ETHEREUM_ENDPOINT\"))\n\npk = os.environ&#91;\"PRIVATE_KEY\"]          # load the key from the environment, never from code\nacct = w3.eth.account.from_key(pk)\n\ntx = {\n    \"type\": 2,\n    \"chainId\": 1,\n    \"to\": \"0xRECIPIENT_ADDRESS\",\n    \"value\": w3.to_wei(0.001, \"ether\"),\n    \"nonce\": w3.eth.get_transaction_count(acct.address, \"pending\"),\n    \"gas\": 21000,\n    \"maxFeePerGas\": w3.to_wei(30, \"gwei\"),\n    \"maxPriorityFeePerGas\": w3.to_wei(1.5, \"gwei\"),\n}\n\nsigned = w3.eth.account.sign_transaction(tx, pk)   # offline: pure signing, no RPC call\ntx_hash = w3.eth.send_raw_transaction(signed.raw_transaction)  # broadcast\nprint(w3.to_hex(tx_hash))<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Two details matter here. The signed object exposes its serialized bytes as <code>signed.raw_transaction<\/code> (snake_case in current web3.py \u2014 older code used <code>rawTransaction<\/code>). And <code>sign_transaction<\/code> itself needs no connection, so on an air-gapped setup you run it on the offline machine and carry <code>signed.raw_transaction<\/code> across to broadcast.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"signing-with-ethersjs-v6-javascript\">Signing with ethers.js v6 (JavaScript)<\/h3>\n\n\n<p class=\"wp-block-paragraph\">In ethers v6, a <code>Wallet<\/code> created without a provider signs offline, and <code>provider.broadcastTransaction<\/code> is the v6 name for submitting the raw result:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">javascript<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { Wallet, JsonRpcProvider, parseEther, parseUnits } from \"ethers\";\n\nconst provider = new JsonRpcProvider(\"YOUR_ETHEREUM_ENDPOINT\");\nconst wallet = new Wallet(process.env.PRIVATE_KEY);   \/\/ no provider attached = offline signer\n\nconst tx = {\n  type: 2,\n  chainId: 1,\n  to: \"0xRECIPIENT_ADDRESS\",\n  value: parseEther(\"0.001\"),\n  nonce: await provider.getTransactionCount(wallet.address, \"pending\"),\n  gasLimit: 21000n,\n  maxFeePerGas: parseUnits(\"30\", \"gwei\"),\n  maxPriorityFeePerGas: parseUnits(\"1.5\", \"gwei\"),\n};\n\nconst rawTx = await wallet.signTransaction(tx);        \/\/ returns the 0x-prefixed signed hex\nconst sent = await provider.broadcastTransaction(rawTx); \/\/ eth_sendRawTransaction under the hood\nconsole.log(sent.hash);\nawait sent.wait();                                      \/\/ wait for the receipt<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>wallet.signTransaction(tx)<\/code> gives you the raw hex string directly. If you want a true air-gap, generate the nonce and fee values ahead of time, build the object on the offline machine, and only <code>broadcastTransaction<\/code> from a connected one.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"the-raw-jsonrpc-call\">The raw JSON-RPC call<\/h3>\n\n\n<p class=\"wp-block-paragraph\">Under both libraries, the broadcast is a single JSON-RPC request. You can send it yourself once you have the signed hex:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">bash<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -X POST https:\/\/eth.nownodes.io \\\n  -H \"api-key: YOUR_API_KEY\" \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\n    \"jsonrpc\": \"2.0\",\n    \"id\": 1,\n    \"method\": \"eth_sendRawTransaction\",\n    \"params\": &#91;\"0xSIGNED_RAW_TRANSACTION_HEX\"]\n  }'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>params<\/code> array holds exactly one item: the raw signed transaction. Nothing about the key or the individual fields appears in the request, because they&#8217;re all baked into that hex string already.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"what-ethsendrawtransaction-returns-and-what-it-doesnt\">What eth_sendRawTransaction Returns, and What It Doesn&#8217;t<\/h2>\n\n\n<p class=\"wp-block-paragraph\">A successful call returns a 32-byte transaction hash right away. That hash is a receipt that the network accepted your transaction into the mempool \u2014 not confirmation that it was mined. As the <a href=\"https:\/\/therpc.io\/docs\/ethereum\/eth_sendRawTransaction\" rel=\"nofollow noopener noreferrer\">RPC method reference<\/a> puts it, the hash is &#8220;not proof that it has been mined.&#8221;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To know the transaction actually landed, poll <code>eth_getTransactionReceipt<\/code> with that hash until it returns a non-null result, then check the receipt&#8217;s <code>status<\/code> field. A status of <code>0x1<\/code> means success; <code>0x0<\/code> means the transaction was included but reverted, and you still paid for the gas it burned.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This two-stage reality \u2014 accepted, then mined \u2014 is why production code almost always waits for the receipt rather than trusting the hash alone.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"common-errors-and-what-they-mean\">Common Errors and What They Mean<\/h2>\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" src=\"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-49-1024x683.png\" alt=\"\" class=\"wp-image-3866\" srcset=\"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-49-1024x683.png 1024w, https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-49-300x200.png 300w, https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-49-768x512.png 768w, https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/image-49.png 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Most failures at broadcast time come from the transaction being built slightly wrong, not from the network being down. These are the ones you&#8217;ll see most:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Error<\/th><th>Cause<\/th><th>Fix<\/th><\/tr><\/thead><tbody><tr><td><code>nonce too low<\/code><\/td><td>The signed nonce is at or below the account&#8217;s current on-chain count<\/td><td>Re-read the nonce with <code>eth_getTransactionCount<\/code> using <code>\"pending\"<\/code>, then re-sign<\/td><\/tr><tr><td><code>insufficient funds for gas * price + value<\/code><\/td><td>The balance can&#8217;t cover the transfer plus maximum gas cost<\/td><td>Lower the value or the fee cap, or fund the account<\/td><\/tr><tr><td><code>replacement transaction underpriced<\/code><\/td><td>You reused a pending nonce but didn&#8217;t raise the fee enough<\/td><td>Bump <code>maxFeePerGas<\/code> and <code>maxPriorityFeePerGas<\/code> by at least ~10%<\/td><\/tr><tr><td><code>already known<\/code><\/td><td>The exact signed transaction is already in the mempool<\/td><td>Wait for it to mine instead of resubmitting<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The recurring theme is the nonce. Because you set it yourself when signing offline, it&#8217;s the field most likely to drift out of sync \u2014 especially when you send several transactions in a row and read <code>\"latest\"<\/code> instead of <code>\"pending\"<\/code> between them.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"where-nownodes-fits\">Where NOWNodes Fits<\/h2>\n\n\n<p class=\"wp-block-paragraph\">Signing is self-contained, but two steps still need a live connection to the network: reading the nonce and fees before you sign, and broadcasting the signed result afterward. That connection is an Ethereum endpoint, and running the client behind it yourself means syncing and maintaining a full archive of the chain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/nownodes.io\/nodes\/ethereum-eth\">NOWNodes<\/a> provides a hosted Ethereum endpoint so an application can read account state and broadcast signed transactions over an API, without operating its own client. The endpoint never holds your key \u2014 it signs nothing \u2014 which is why <code>eth_sendRawTransaction<\/code> is the method you use against it. It relays the signed hex you built locally, and because the signature covers every field, the endpoint can forward or reject the transaction but can&#8217;t change it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For testing the flow before going near mainnet funds, the <a href=\"https:\/\/nownodes.io\/public-endpoints\">public endpoints<\/a> offer keyless access for light reads, and the free Start plan includes 100,000 requests once you need an API key. A sensible order is to sign and broadcast against a testnet first, confirm the receipt status comes back as success, then switch the chain ID and endpoint to mainnet. The code doesn&#8217;t change; only the target does.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n<p class=\"wp-block-paragraph\">Signing offline and broadcasting with <code>eth_sendRawTransaction<\/code> comes down to keeping two jobs apart. Signing is local math that turns your transaction and key into a tamper-proof blob of hex, and it needs no network at all. Broadcasting is a single JSON-RPC call that pushes that blob into the mempool and hands you a hash. Keep the key on the signing side of that line, set the nonce and chain ID yourself with care, and wait for the receipt rather than trusting the hash, and you have a transaction flow that works the same whether you&#8217;re sending from a script, a backend, or an air-gapped cold wallet.<\/p>\n\n\n<h2 class=\"wp-block-heading\" id=\"faq\">FAQ<\/h2>\n\n<h3 class=\"wp-block-heading\" id=\"whats-the-difference-between-ethsendtransaction-and-ethsendrawtransaction\">What&#8217;s the difference between eth_sendTransaction and eth_sendRawTransaction?<\/h3>\n\n\n<p class=\"wp-block-paragraph\"><code>eth_sendTransaction<\/code> asks the client to sign for you, which only works if it holds your unlocked key. <code>eth_sendRawTransaction<\/code> takes a transaction you already signed yourself and just relays it. Hosted endpoints support the second because they never hold your key.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"does-signing-a-transaction-cost-gas\">Does signing a transaction cost gas?<\/h3>\n\n\n<p class=\"wp-block-paragraph\">No. Signing is a local operation with no network interaction, so it&#8217;s free. Gas is only spent when the transaction is mined, and it&#8217;s charged against the sender&#8217;s balance at that point \u2014 not when you sign.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"can-the-endpoint-i-broadcast-through-steal-or-change-my-transaction\">Can the endpoint I broadcast through steal or change my transaction?<\/h3>\n\n\n<p class=\"wp-block-paragraph\">It can refuse to relay the transaction, but it can&#8217;t alter it. Every field is covered by your signature, so any edit \u2014 to the amount, recipient, or gas \u2014 invalidates the signature and the network rejects the result.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"why-does-my-transaction-keep-failing-with-nonce-too-low\">Why does my transaction keep failing with &#8220;nonce too low&#8221;?<\/h3>\n\n\n<p class=\"wp-block-paragraph\">The nonce you signed is at or below the account&#8217;s current count, usually because it was read as <code>\"latest\"<\/code> while an earlier transaction was still pending. Re-read the count with the <code>\"pending\"<\/code> tag and sign again.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"do-i-need-an-archive-endpoint-to-broadcast-a-signed-transaction\">Do I need an archive endpoint to broadcast a signed transaction?<\/h3>\n\n\n<p class=\"wp-block-paragraph\">No. Broadcasting only needs a standard endpoint that can accept <code>eth_sendRawTransaction<\/code> and read current account state. Archive access matters for querying old historical state, not for sending new transactions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To sign an Ethereum transaction offline, you build the transaction, sign it locally with your private key, and get back a serialized blob of hex. Then you hand that blob to the network with eth_sendRawTransaction, which checks it and drops it into the mempool. The signing and the sending are two separate acts, and the [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":3865,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_eb_attr":"","_lmt_disableupdate":"","_lmt_disable":"","_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[102],"tags":[],"class_list":["post-3863","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dev-report"],"blocksy_meta":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.0 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Sign an Ethereum Transaction Offline &amp; Broadcast It<\/title>\n<meta name=\"description\" content=\"How to sign an Ethereum transaction offline with your private key and push it live using eth_sendRawTransaction \u2014 the fields, working code, and error fixes.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sign an Ethereum Transaction Offline &amp; Broadcast It\" \/>\n<meta property=\"og:description\" content=\"How to sign an Ethereum transaction offline with your private key and push it live using eth_sendRawTransaction \u2014 the fields, working code, and error fixes.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/\" \/>\n<meta property=\"og:site_name\" content=\"NOWNodes Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-08T11:29:23+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-08T11:29:25+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/text_2-18.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1800\" \/>\n\t<meta property=\"og:image:height\" content=\"900\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"\u0410nastasia\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nownodes\" \/>\n<meta name=\"twitter:site\" content=\"@nownodes\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u0410nastasia\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/\"},\"author\":{\"name\":\"\u0410nastasia\",\"@id\":\"https:\/\/nownodes.io\/blog\/#\/schema\/person\/0890ec68e813adecb93c18ee00e1e7a8\"},\"headline\":\"How to Sign a Transaction Offline and Broadcast It with eth_sendRawTransaction\",\"datePublished\":\"2026-10-08T11:29:23+00:00\",\"dateModified\":\"2026-10-08T11:29:25+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/\"},\"wordCount\":1965,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/nownodes.io\/blog\/#organization\"},\"articleSection\":[\"Dev Report\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/\",\"url\":\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/\",\"name\":\"Sign an Ethereum Transaction Offline & Broadcast It\",\"isPartOf\":{\"@id\":\"https:\/\/nownodes.io\/blog\/#website\"},\"datePublished\":\"2026-10-08T11:29:23+00:00\",\"dateModified\":\"2026-10-08T11:29:25+00:00\",\"description\":\"How to sign an Ethereum transaction offline with your private key and push it live using eth_sendRawTransaction \u2014 the fields, working code, and error fixes.\",\"breadcrumb\":{\"@id\":\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Blog\",\"item\":\"https:\/\/nownodes.io\/blog\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Dev Report\",\"item\":\"https:\/\/nownodes.io\/blog\/category\/dev-report\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Sign a Transaction Offline and Broadcast It with eth_sendRawTransaction\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/nownodes.io\/blog\/#website\",\"url\":\"https:\/\/nownodes.io\/blog\/\",\"name\":\"NOWNodes Blog\",\"description\":\"Your first-to-go source of development guides, web3 analytics and most recent news about NOWNodes\",\"publisher\":{\"@id\":\"https:\/\/nownodes.io\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/nownodes.io\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/nownodes.io\/blog\/#organization\",\"name\":\"NOWNodes Blog\",\"url\":\"https:\/\/nownodes.io\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/nownodes.io\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2024\/02\/cropped-New-Logo-NN.png\",\"contentUrl\":\"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2024\/02\/cropped-New-Logo-NN.png\",\"width\":1164,\"height\":1164,\"caption\":\"NOWNodes Blog\"},\"image\":{\"@id\":\"https:\/\/nownodes.io\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/twitter.com\/nownodes\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/nownodes.io\/blog\/#\/schema\/person\/0890ec68e813adecb93c18ee00e1e7a8\",\"name\":\"\u0410nastasia\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/nownodes.io\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1de24ab8dcdd7ec30f6adaf78b56bc1eda421f87575b7e103c8fc3fc4420e833?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1de24ab8dcdd7ec30f6adaf78b56bc1eda421f87575b7e103c8fc3fc4420e833?s=96&d=mm&r=g\",\"caption\":\"\u0410nastasia\"},\"url\":\"https:\/\/nownodes.io\/blog\/author\/nasty-nownodes\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Sign an Ethereum Transaction Offline & Broadcast It","description":"How to sign an Ethereum transaction offline with your private key and push it live using eth_sendRawTransaction \u2014 the fields, working code, and error fixes.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/","og_locale":"en_US","og_type":"article","og_title":"Sign an Ethereum Transaction Offline & Broadcast It","og_description":"How to sign an Ethereum transaction offline with your private key and push it live using eth_sendRawTransaction \u2014 the fields, working code, and error fixes.","og_url":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/","og_site_name":"NOWNodes Blog","article_published_time":"2026-10-08T11:29:23+00:00","article_modified_time":"2026-10-08T11:29:25+00:00","og_image":[{"width":1800,"height":900,"url":"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2026\/10\/text_2-18.jpg","type":"image\/jpeg"}],"author":"\u0410nastasia","twitter_card":"summary_large_image","twitter_creator":"@nownodes","twitter_site":"@nownodes","twitter_misc":{"Written by":"\u0410nastasia","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#article","isPartOf":{"@id":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/"},"author":{"name":"\u0410nastasia","@id":"https:\/\/nownodes.io\/blog\/#\/schema\/person\/0890ec68e813adecb93c18ee00e1e7a8"},"headline":"How to Sign a Transaction Offline and Broadcast It with eth_sendRawTransaction","datePublished":"2026-10-08T11:29:23+00:00","dateModified":"2026-10-08T11:29:25+00:00","mainEntityOfPage":{"@id":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/"},"wordCount":1965,"commentCount":0,"publisher":{"@id":"https:\/\/nownodes.io\/blog\/#organization"},"articleSection":["Dev Report"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/","url":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/","name":"Sign an Ethereum Transaction Offline & Broadcast It","isPartOf":{"@id":"https:\/\/nownodes.io\/blog\/#website"},"datePublished":"2026-10-08T11:29:23+00:00","dateModified":"2026-10-08T11:29:25+00:00","description":"How to sign an Ethereum transaction offline with your private key and push it live using eth_sendRawTransaction \u2014 the fields, working code, and error fixes.","breadcrumb":{"@id":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/nownodes.io\/blog\/how-to-sign-a-transaction-offline-and-broadcast-it-with-eth_sendrawtransaction\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Blog","item":"https:\/\/nownodes.io\/blog"},{"@type":"ListItem","position":2,"name":"Dev Report","item":"https:\/\/nownodes.io\/blog\/category\/dev-report"},{"@type":"ListItem","position":3,"name":"How to Sign a Transaction Offline and Broadcast It with eth_sendRawTransaction"}]},{"@type":"WebSite","@id":"https:\/\/nownodes.io\/blog\/#website","url":"https:\/\/nownodes.io\/blog\/","name":"NOWNodes Blog","description":"Your first-to-go source of development guides, web3 analytics and most recent news about NOWNodes","publisher":{"@id":"https:\/\/nownodes.io\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/nownodes.io\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/nownodes.io\/blog\/#organization","name":"NOWNodes Blog","url":"https:\/\/nownodes.io\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/nownodes.io\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2024\/02\/cropped-New-Logo-NN.png","contentUrl":"https:\/\/nownodes.io\/blog\/wp-content\/uploads\/2024\/02\/cropped-New-Logo-NN.png","width":1164,"height":1164,"caption":"NOWNodes Blog"},"image":{"@id":"https:\/\/nownodes.io\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/twitter.com\/nownodes"]},{"@type":"Person","@id":"https:\/\/nownodes.io\/blog\/#\/schema\/person\/0890ec68e813adecb93c18ee00e1e7a8","name":"\u0410nastasia","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/nownodes.io\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/1de24ab8dcdd7ec30f6adaf78b56bc1eda421f87575b7e103c8fc3fc4420e833?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1de24ab8dcdd7ec30f6adaf78b56bc1eda421f87575b7e103c8fc3fc4420e833?s=96&d=mm&r=g","caption":"\u0410nastasia"},"url":"https:\/\/nownodes.io\/blog\/author\/nasty-nownodes"}]}},"modified_by":"\u0410nastasia","_links":{"self":[{"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/posts\/3863","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/comments?post=3863"}],"version-history":[{"count":1,"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/posts\/3863\/revisions"}],"predecessor-version":[{"id":3867,"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/posts\/3863\/revisions\/3867"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/media\/3865"}],"wp:attachment":[{"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/media?parent=3863"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/categories?post=3863"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nownodes.io\/blog\/wp-json\/wp\/v2\/tags?post=3863"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}