Mainnet contract deploy: 100% rejection with Substrate `1016 Immediately Dropped` despite empty pool, sufficient DUST, and 100× fee bump

Hi all — sharing a deterministic Mainnet deploy failure to see if anyone else hits the same wall, and to ask the core team for a node-side log lookup.

## Symptom

Compact contract deploy on Mainnet fails at submit with:

RPC-CORE: submitAndWatchExtrinsic(extrinsic: Extrinsic): ExtrinsicStatus:: 1016: Immediately Dropped: The transaction couldn’t enter the pool because of the limit

DEPLOY FAILED: SubmissionError: Transaction submission error at @midnight-ntwrk/wallet-sdk-capabilities/dist/submission/submissionService.js:31


7 attempts on 2026-04-29 (UTC), all failing at the same point. Client-side stages (sync, DUST detection, providers, ZK proof generation) all succeed; node submission is rejected ~5 seconds after `Deploying ...` log line.

## Setup

- Wallet (submitter): `mn_addr18ehfpzy7hyyj4gm6kt7zkwkejc3sg629yr23tsvjs8kjaf754yvqetqsrz`
- DUST balance: ~351,000 DUST in 1 UTXO (cross-wallet model: cNIGHT held in Cardano Lace wallet B, DUST registered to this Mainnet address)
- DUST balance is growing at the expected rate (+10k DUST in ~6 h via two reads of the indexer)
- Mainnet node version: `0.22.1-9ce45781`
- RPC: public `https://rpc.mainnet.midnight.network`
- SDK: `wallet-sdk-facade@3.0.0`, `wallet-sdk-dust-wallet@3.0.0`, `ledger-v8@8.0.3`, `compact-runtime@0.15.0`, `midnight-js@4.0.4`
- Proof server: local `:6300`
- Compact compiler: `0.5.1` (deterministic — recompile produced byte-identical artifacts)

> Note: SDK was upgraded after we identified and fixed 12 Iterator Helpers bugs (forum thread: https://forum.midnight.network/t/12-iterator-helpers-bugs-in-midnight-sdk-under-node-v22-array-from-workarounds-included/1184), so the rejection here is **not** from those known issues.

## Hypotheses ruled out

1. **Pool overflow** — `author_pendingExtrinsics` returns `[]` (empty) immediately before failed attempts.
2. **Fee priority** — `additionalFeeOverhead` raised 100× (0.3 → 30 DUST). Same identical rejection. SDK testkit default of `5e20` (500k DUST) exceeds my balance, but 100× should have moved the needle if priority were the cause.
3. **Insufficient balance** — 351k DUST is ~5 orders of magnitude above any expected fee.
4. **Wallet observability** — same wallet seed reads on-chain DUST UTXO correctly via `scripts/check-mainnet-balance.ts` (which I rewrote `src/mainnet.ts` to mirror, after `api.buildWalletAndWaitForFunds` had separate hang issues).
5. **ZK proof generation** — succeeds; the 1016 fires after proof gen.
6. **TX mortality** — 3.5+ hours between attempts; far beyond the 256-block (25 min) longevity window.
7. **Time of day** — tried both BKK afternoon (US morning UTC) and BKK early morning (US late afternoon UTC).

## Open questions for the team

1. Are deploys from a fresh wallet (no prior tx history) being throttled or filtered Mainnet-side?
2. Does the public RPC load-balance `submitAndWatchExtrinsic` to a different node than `author_pendingExtrinsics`, masking a per-node pool issue?
3. Is `1016` here actually pool-pressure, or is it Substrate's generic mapping for a runtime-validation rejection (e.g. `InvalidTransaction`)?
4. Is there node-side log visibility for submit attempts from `mn_addr18ehfpzy7…` around 2026-04-29 14:39 UTC, 2026-04-29 18:48 UTC, and 2026-04-29 19:27 UTC?

## Question for other builders

Has anyone else successfully deployed a fresh Compact contract to Mainnet recently? If so:
- Was your submitter wallet "warmed up" with a prior tx (NIGHT transfer, etc.)?
- Did you see anything similar to 1016 along the way?
- Are you on public `rpc.mainnet.midnight.network` or a private node?

## What works (Preview track record)

For context: GYOTAK has been running on Midnight Preview for 8 days with 13 catch records successfully recorded on-chain via a cron job (publishing summary at https://gyotak-blog.pages.dev/). The Mainnet migration is the only blocker preventing production deployment.

`scripts/check-mainnet-balance.ts` (read-only wallet sync + DUST balance read) also works flawlessly with the same seed/network/SDK, confirming the wallet itself is correctly registered, observable, and funded. The blocker is strictly node-side at submit time.

Happy to share more detail on request — full logs, sanitised seed derivation path, etc.

— GYOTAK project (catch-record dapp on Midnight; Preview cron operational since 2026-04-21)

Hi @takuya — we hit this exact issue 30 days after your post and want to consolidate evidence with you.

Same symptom (2026-05-29, independent stack)

1016 Immediately Dropped on rpc.mainnet.midnight.network, author_pendingExtrinsics empty before submit, sufficient DUST in wallet, ZK proof generation succeeds, rejection fires ~seconds after the Deploying ... log line. Cross-wallet model: cNIGHT on a Cardano wallet, DUST on a separate Midnight wallet (different mnemonics — same setup as yours).

Extending your “hypotheses ruled out” list

We did 42 days of mainnet RPC sampling (2026-04-18 → 2026-05-30) + ledger-v8@8.0.3 deserialize of every reachable successful ContractDeploy we could find on chain (3 in the entire window). Adds to your existing eliminations:

  • Wire format — all 3 successful deploys use transaction[v9](signature[v1],proof,pedersen-schnorr[v1]). ledger-v8@8.0.3 WASM contains the v9 string and the SDK emits v9. No mismatch.
  • Tx size — successful deploys are 10KB / 18KB / 28KB. Our attempted deploy is ~1.7KB. Size is not the gate.
  • SDK version regressionwallet-sdk-facade@3.0.0 (your stack) and @4.1.0 produce byte-identical proven constructor txs at ~1773 bytes; both compute tx.fees(currentParams) = 1 Speck.
  • Cost model differentialoverallPrice has drifted 18 orders of magnitude from genesis 10 to 5.42e-18 on both mainnet AND preprod (direct query of latest block.ledgerParameters on each). The two networks are no longer different here. tx.fees() returns 1 Speck for all 3 successful deploys under current params — matching what our wallet calculates exactly.
  • Unshielded-layer identity — all 3 successful deploys have zero unshielded UTXOs (unshieldedSpentOutputs + unshieldedCreatedOutputs both empty per the mainnet indexer). Our failed deploy is also pure DUST-only with zero unshielded UTXOs. No structural difference on the unshielded surface — no observable deployer-identity leak to filter on.

What remains [unknown]

The differentiator between the 3 successful deploys and our + your failed attempts is not in any client-side or tx-content layer we can measure. It must be at the submission / pool admission / node-policy layer (echoes your open question #2 about RPC load-balancing).

We were not able to run system_dryRun (which would surface the inner InvalidTransaction::Custom(N) code behind the generic 1016 wrapper). balanceUnboundTransaction requires a fully-synced DUST wallet, and preprod’s ~880K event history OOMs a fresh local environment at 8GB / ~13hr sync — practically not reproducible without a pre-warmed wallet. This remains the highest-value unrun diagnostic.

Two asks

1. @takuya — any progress, workaround, or private Midnight team response in the past month?

  • Did any “warming” experiment (NIGHT self-transfer to your own address before deploy, etc.) move the needle?
  • Did switching to a non-public RPC endpoint help?

2. Midnight team — is there a node-side filter, allowlist, or off-chain coordination step that gates ContractDeploy submission on mainnet? The empirical pattern (only 3 successful deploys in 42 days of sampling, all named-partner-grade contracts) is consistent with such a gate, but no public documentation describes one. If intentional, knowing the criteria would unblock the community; if a bug, knowing the inner reject code would unblock debugging.

Reference data (3 successful mainnet deploys in our sampling window)

Date (UTC) Block Contract address Entry points (highlights) TX size
2026-03-29 152533 27f184bd009bef633ab461ff50df2bb669e4448871e4b080439e9da30afb919d register, claim, receive_name 10,070 B
2026-05-22 921123 fb0ac474fe32f09b655ad240a67e518f675f0235e52072caef67d5e1dcc83226 orderbook DEX (8 entry points incl. placeOrder, settleBatch) 18,036 B
2026-05-30 1037345 c141c5a5a969d7e9416ff8e0ff399acb2eca4367a87563e3550ccdbd2bd433c0 governance/permission (≥9 entry points incl. grant_permission, rotate_epoch) 28,192 B

Happy to share deserialized intent structures, cost-model calculations, or full hex on request.

-– independent builder running a privacy-anchoring service on Midnight; hit the identical wall on first mainnet deploy attempt

Thanks @1491sc so sorry you’re hitting the same wall as @takuya.

I don’t have a team update from the past month, and there’s no public doc describing a mainnet ContractDeploy allowlist or off-chain coordination step. Mainnet is open in principle (DUST for fees, matrix-compatible SDK, deploy via midnight-js), but I can’t confirm or deny node-side filtering from here that needs engineering triage.

1016 Immediately Dropped is a Substrate pool rejection, not the ledger Custom(N) you get on a typical 1010. Still capture the full JSON-RPC error (including data) on submit sometimes there’s an inner code; if not, it may be upstream validation (signature, nonce, era) before ledger logic runs. See Decode 1010 errors and the error code tables (174 MalformedContractDeploy, 233/234, 110 VerifierKeyNotSet, 155 FeeCalculationError, etc.).

system_dryRun is the highest-value next step agreed. Without it we’re guessing. If preprod sync/OOM blocks that locally, a pre-warmed wallet or a machine with enough RAM for a one-off dryRun is worth it.

One thing your data flags: successful mainnet deploys in your window are ~10–28 KB; your attempted deploy is ~1.7 KB. That gap may mean a different deploy shape (e.g. missing verifier keys / contract state bundle), not just fees worth comparing your serialized deploy intent to a known-good mainnet deploy, not only wire version tags.

Cross-wallet cNIGHT + separate DUST wallet is a valid mainnet setup; docs focus on DUST registration/accrual for fees ensure DUST is registered, fresh, and on the wallet signing the deploy.

Please file at the MNF Service Desk (Bug, network Mainnet, component App/SDK or Node) with: full RPC 1016 JSON, proven tx hex, SDK/matrix versions, DUST balance + registration state, and your 42-day comparison table. Drop the ticket link here. and i will follow up on it

@takuya if anything changed on your side (dryRun result, alternate RPC, warming), please share.

@nasihudeenJ — filed Service Desk ticket: Mainnet contract deploy: 100% rejection with Substrate `1016 Immediately Dropped` (independent reproduction of forum #1190) · Issue #34 · midnightntwrk/servicedesk · GitHub

It contains all 5 items you requested: full RPC 1016 string (with attribution limit disclosed), captured tx hex with SHA256 + decoded wire-format tag, SDK matrix (direct 23 + transitive 7), DUST balance trajectory + registration state, and the 42-day independent reproduction with comparison against 3 accepted mainnet deploys.


Two corrections to my reply above, for the record:

  1. SDK version reference — I wrote “@4.1.0 produce byte-identical” alongside wallet-sdk-facade@3.0.0. Our worker’s facade is actually @4.0.1; 4.1.0 is the midnight-js-* family version. The cross-SDK finding still stands at the proven constructor tx layer (~1,773 bytes either stack); only the version label was imprecise.

  2. Fee wording — “tx.fees() returns 1 Speck for all 3 successful deploys” was based on a client-side deserialization that I now suspect was returning a default field rather than ground-truth on-chain values. The ticket above withholds the v_fee column entirely pending direct verification by the node ops team.

Apologies for the imprecisions.

No worries Thanks for opening the issue i will take it up from here and you can also track the progress from the issue you opened
Thanks again

Thanks for the thorough ticket (#34) and the corrections that helped.

Update from the team: during mainnet guarded launch, public nodes are expected to drop contractDeploy transactions on purpose. Mainnet deploys need API keys from the MIP deploy request process not the public RPC path alone. So 1016 Immediately Dropped with empty pool + valid-looking tx can be intentional admission control, not a client bug.

If you’re aiming for mainnet deploy: midnight-improvement-proposals/deployments/contract-deployment-rubric.md at main · midnightntwrk/midnight-improvement-proposals · GitHub

For development, preprod / preview / local undeployed remain the paths without that gate. Sorry for the long detour your analysis wasn’t wasted, but the blocker here is launch policy, not your ~1.7 KB wire format.