Errors
Every carbon_core::error::Error variant in Carbon 2.0.0 with its message, cause and fix, plus common errors from RPC, rustls and Cargo.
On this page
- How Carbon reports errors
- FailedToConsumeDatasource
- Custom
- MissingFeePayer
- MissingAccountInTransaction
- MissingUpdateTypeInDatasource
- FailedToReceiveUpdates
- MissingInnerInstructions
- MissingInstructionData
- ConversionError
- Related errors
- Method not found for blockSubscribe
- 429 Too Many Requests
- Could not automatically determine the process-level CryptoProvider
- there are multiple different versions of crate carbon_
core - Failed to decode transaction with Json encoding
- Full(..) when sending updates
- Invalid inner instruction stack height
- Ctrl-C does not stop the pipeline
This page lists every variant of carbon_ in Carbon 2.0.0 as error → cause → fix, followed by errors that come from Carbon's dependencies but show up in Carbon pipelines. For how errors flow through a pipeline, see Error handling.
Source: crates/.
How Carbon reports errors#
#[derive(Error, Debug)]
pub enum Error {
#[error("Missing update type in datasource")]
MissingUpdateTypeInDatasource(UpdateType),
#[error("Failed to receive updates({0})")]
FailedToReceiveUpdates(String),
#[error("Transaction missing fee payer")]
MissingFeePayer,
#[error("Missing inner instructions")]
MissingInnerInstructions,
#[error("Missing account in transaction")]
MissingAccountInTransaction,
#[error("Missing instruction data")]
MissingInstructionData,
#[error("Failed to consume datasource ({0})")]
FailedToConsumeDatasource(String),
#[error("Custom error: {0}")]
Custom(String),
}
pub type CarbonResult<T> = Result<T, Error>;The pipeline logs errors with {:?}, so logs show the Debug form (FailedToConsumeDatasource("Failed to fetch program accounts")), not the Display message. Both forms are listed below. Where an error surfaces decides what happens next:
| Where it is returned | Log line (error level, target carbon_) | Effect |
|---|---|---|
Datasource:: | error consuming datasource: < | That datasource stops. The others keep running. When none are left, the pipeline drains the channel and run returns Ok(()). |
A decoder step or Processor:: | error processing update (< | The update is counted in carbon_; the remaining pipes for that update are skipped; processing continues. |
| A metrics exporter | none | Pipeline:: returns the error. |
Enable logs with a logger such as env_logger and RUST_ (Carbon's own messages are at info, warn and error).
FailedToConsumeDatasource#
Error. Failed to consume datasource (<. Logged as error consuming datasource: FailedToConsumeDatasource("<.
Cause. A datasource's consume could not start or continue. Built-in producers and their messages:
| Datasource | Messages |
|---|---|
| RPC GPA | Failed to fetch program accounts (any RPC or deserialization failure of getProgramAccounts, including rate limits and timeouts); Failed to parse pubkey: …; Failed to decode account |
| Helius GPA V2 | HTTP request failed: …, Failed to parse response: …, RPC error: <, Response missing context or value field |
| Helius GTFA | Failed to serialize request config: …, HTTP request failed: …, HTTP error <, Failed to parse response: …, RPC error: <, Response missing result field |
| Yellowstone gRPC, Helius LaserStream | The tonic or client error text when building the endpoint, setting x_token, or connecting (invalid URL, DNS, TLS, refused connection, bad token) |
| Validator snapshot | Ledger directory does not exist: …, Genesis archive not found: …. Expected genesis., No loadable full snapshot archive found in …, Failed to load bank forks from snapshot: …, Invalid snapshot: loaded bank has slot 0, …, download errors such as Failed to download <, Scan failed: … |
Fix. Read the message after the variant name; it names the failing step.
- For connection errors, check the endpoint URL and scheme (
https://for TLS gRPC), the token, and network access. - For
Failed to fetch program accountson the public endpoint, addfilters(such as adataSizeormemcmpon the discriminator) toRpcProgramAccountsConfig: unfilteredgetProgramAccountson large programs times out or is rejected. Use a paid RPC for large programs. - For snapshot errors, check the paths and that the archive matches the cluster.
- Restart the pipeline, or wrap the datasource in your own retry loop: datasources don't restart themselves after
consumereturns.
See also. Datasources, Load account state, Load a snapshot.
Custom#
Error. Custom error: <. Logged as Custom("<.
Cause. A catch-all used by:
| Producer | Message |
|---|---|
| RPC block subscribe | Failed to create RPC subscribe client after 10 attempts: …, Failed to subscribe after 10 attempts: … |
| RPC program subscribe | Failed to create RPC subscribe client after 10 attempts: …, Failed to subscribe after 10 attempts: … |
| Helius Atlas WebSocket | Error creating Filters for the Helius WebSocket: accounts and transactions can't be both empty, Failed to create Helius client after … attempts: … |
carbon_ and generated Postgres code | The sqlx error text, or out of range, invalid numeric string, value exceeds maximum for target type, invalid scale for i128, invalid sign/ |
| Your code | Anything you wrap, for example Error:: |
The subscribe datasources wait 3 seconds between attempts.
Fix. For subscribe failures, read the wrapped error: Method not found (-32601) means the endpoint doesn't support the method (see blockSubscribe is not supported); connection errors mean a wrong wss:// URL or a blocked network. For Atlas, pass at least one account or transaction filter. For Postgres errors, see the Postgres reference. In your own code, prefer Custom with a descriptive message over unwrap, so the pipeline logs the failure and continues.
See also. Stream with RPC, Postgres.
MissingFeePayer#
Error. Transaction missing fee payer. Logged as error processing update (Transaction(…)): MissingFeePayer.
Cause. The pipeline converts each TransactionUpdate into TransactionMetadata and takes the fee payer from the first static account key of the message. The message has no account keys. Built-in datasources never send such transactions; it happens when a custom datasource builds a VersionedTransaction with an empty or default message.
Fix. Build TransactionUpdate:: from the full decoded transaction (for RPC, EncodedTransaction:: on a Base64 payload), not from VersionedTransaction::. The update is skipped and the pipeline continues.
See also. TransactionUpdate, Custom datasource.
MissingAccountInTransaction#
Error. Missing account in transaction. Logged as MissingAccountInTransaction.
Cause. Returned only by the public helper carbon_ when an account index points past the message's static account keys. The pipeline does not call this helper. It happens when you call it on a V0 transaction whose instruction uses accounts from an address lookup table, because the helper ignores meta..
Fix. Use the instruction the pipeline already built (raw_ in instruction processors, or NestedInstruction::), whose accounts include lookup-table addresses. If you need the helper, append meta. and readonly to the keys yourself.
See also. InstructionProcessorInputType.
MissingUpdateTypeInDatasource#
Error. Missing update type in datasource. Logged as MissingUpdateTypeInDatasource(<.
Cause. Nothing in Carbon 2.0.0 returns this variant. It is reserved for checking a datasource's update_ against registered pipes, which the 2.0.0 pipeline does not do.
Fix. If you see it, it comes from your own code or a third-party crate; read that code. Carbon itself does not validate update_.
See also. UpdateType.
FailedToReceiveUpdates#
Error. Failed to receive updates(< (no space before the parenthesis). Logged as FailedToReceiveUpdates("<.
Cause. Not returned anywhere in Carbon 2.0.0. Available for custom datasources that lose their upstream stream.
Fix. Read the wrapped message from the datasource that returned it. If you write a datasource, either variant is fine; FailedToConsumeDatasource is what the built-in ones use.
See also. Datasource.
MissingInnerInstructions#
Error. Missing inner instructions. Logged as MissingInnerInstructions.
Cause. Not returned anywhere in Carbon 2.0.0. When meta. is None, the pipeline treats the transaction as having no CPIs instead of failing.
Fix. If CPIs are missing from your processors, the source did not send inner instructions: for custom RPC datasources, request transaction_; for Yellowstone, use a full transaction subscription. See also invalid inner instruction stack height.
See also. Instructions.
MissingInstructionData#
Error. Missing instruction data. Logged as MissingInstructionData.
Cause. Not returned anywhere in Carbon 2.0.0.
Fix. Read the code that returned it; decoders signal "not mine" by returning None, not this error.
See also. InstructionDecoder.
ConversionError#
Error. A separate error type, carbon_ (behind carbon-core's yellowstone feature). Its variants and Display messages:
MissingField(field) missing required protobuf field `<field>`
InvalidByteLength { field, expected, actual } invalid byte length for `<field>`: expected <expected>, got <actual>
IntegerOutOfRange { field, value } value <value> for `<field>` does not fit in a u8
InvalidEnum { field, value } invalid enum value <value> for `<field>`
InvalidNumber { field, value } invalid numeric value `<value>` for `<field>`
InvalidTransactionError(_) failed to decode the protobuf transaction error with wincodeCause. The Yellowstone and LaserStream datasources convert protobuf transactions with create_ and create_. A malformed or incompatible message fails the conversion. They log Failed to create transaction meta: < and skip that transaction; a failed create_ skips the transaction silently.
Fix. Usually a server running a Yellowstone protocol version that doesn't match yellowstone-grpc-proto 12.7 (Carbon 2.0.0's pin). Check the provider's version. The pipeline continues with the next transaction.
See also. Stream with Yellowstone.
Related errors#
These errors don't come from carbon_, but readers hit them while running Carbon pipelines.
Method not found for blockSubscribe#
Error. With RpcBlockSubscribe on wss:/:
[2026-11-09T00:15:41Z ERROR carbon_rpc_block_subscribe_datasource] Failed to subscribe to block updates: SubscribeFailed { reason: "Method not found (-32601)", message: "{\"jsonrpc\":\"2.0\",\"error\":{\"code\":-32601,\"message\":\"Method not found\"},\"id\":1}" }
[2026-11-09T00:16:42Z ERROR carbon_core::pipeline] error consuming datasource: Custom("Failed to subscribe after 10 attempts: subscribe failed: Method not found (-32601)")
[2026-11-09T00:16:42Z INFO carbon_core::pipeline] update_receiver closed, shutting down.
[2026-11-09T00:16:42Z INFO carbon_core::pipeline] pipeline shutdown complete.Cause. blockSubscribe is an unstable RPC method that validators only serve with --rpc-pubsub-enable-block-subscription. Solana's public endpoints don't enable it. The datasource retries 11 times, 3 seconds apart, then gives up, and the pipeline exits with status 0.
Fix. Use an RPC provider that supports blockSubscribe, or switch datasource: the RPC transaction crawler works on the public endpoint for one program's history, and Yellowstone gRPC or Helius LaserStream stream every block.
See also. Stream with RPC.
429 Too Many Requests#
Error. With the RPC transaction crawler (or GPA) on the public endpoint, at RUST_:
[2026-11-09T00:18:44Z DEBUG solana_rpc_client::http_sender] Too many requests: server responded with Response { url: "https://api.mainnet-beta.solana.com/", status: 429, headers: {…, "retry-after": "10", …} }and, once the client's own retries are exhausted, at warn and error level:
[2026-11-09T00:19:39Z WARN carbon_rpc_transaction_crawler_datasource] Failed to fetch transaction 2RPWo3shvDtwGNSD2tY79uwFJ6Gbx1M7g5knfsJEDpcdahojCL8csGJV6KCEyvzZC2UhBnctSPcFSwSPr4i4jHct (attempt 1/3), retrying in 1000ms: Error { request: Some(GetTransaction), kind: Reqwest(reqwest::Error { kind: Status(429, None), url: "https://api.mainnet-beta.solana.com/" }) }Cause. The public endpoint rate-limits per IP. solana-rpc-client retries 429s internally (logged at debug), then the crawler retries with backoff (RetryConfig::: 3 retries, 1 s initial, ×2, 10 s max). After the last retry it logs Failed to fetch transaction < and skips that transaction.
Fix.
- Lower
ConnectionConfig::(default 5) and raisemax_ concurrent_ requests polling_.interval - Raise
RetryConfig::and the backoff so fewer transactions are skipped.max_ retries - For anything beyond a demo, use a paid RPC endpoint.
See also. Backfill transactions, RPC transaction crawler.
Could not automatically determine the process-level CryptoProvider#
Error. At startup, with the Yellowstone gRPC or Helius LaserStream datasource and a TLS (https://) endpoint:
thread 'tokio-rt-worker' panicked at /home/you/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.46/src/crypto/mod.rs:249:14:
Could not automatically determine the process-level CryptoProvider from Rustls crate features.
Call CryptoProvider::install_default() before this point to select a provider manually, or make sure exactly one of the 'aws-lc-rs' and 'ring' features is enabled.
See the documentation of the CryptoProvider type for more information.
[2026-11-09T00:51:58Z INFO carbon_core::pipeline] update_receiver closed, shutting down.
[2026-11-09T00:51:58Z INFO carbon_core::pipeline] pipeline shutdown complete.Cause. The gRPC stack pulls in rustls 0.23 with both the ring and aws-lc-rs backends, so rustls can't pick one. The panic happens inside the datasource's task, so the pipeline logs a clean shutdown and exits with status 0.
Fix. Install a provider once at the start of main, before building the datasource:
[dependencies]
rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs"] }rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.expect("failed to install the rustls crypto provider");See also. Stream with Yellowstone, Stream with LaserStream.
there are multiple different versions of crate carbon_ core#
Error. At compile time, when a Carbon 1.x crate is mixed with Carbon 2.0.0:
error[E0277]: the trait bound `for<'a> MemoProgramDecoder: InstructionDecoder<'a>` is not satisfied
--> src/main.rs:19:53
|
19 | let _pipeline = Pipeline::builder().instruction(MemoProgramDecoder, Memos).build()?;
| ----------- ^^^^^^^^^^^^^^^^^^ the trait `for<'a> InstructionDecoder<'a>` is not implemented for `MemoProgramDecoder`
| |
| required by a bound introduced by this call
|
note: there are multiple different versions of crate `carbon_core` in the dependency graph
--> /home/you/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/carbon-core-2.0.0/src/instruction.rs:187:1
|
187 | pub trait InstructionDecoder<'a> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is the expected trait
|
::: /home/you/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/carbon-core-1.0.0/src/instruction.rs:188:1
|
188 | pub trait InstructionDecoder<'a> {
| -------------------------------- this is the found traitCause. Here carbon-memo-program-decoder = "1. sits next to carbon-core = "2., so two carbon_core crates are compiled and the decoder implements the 1.x trait. The same happens with Solana types: Carbon 1 uses the Solana 3 crates (solana-account 3, solana-transaction-status 3) and Carbon 2 the Agave 4.2 cohort (solana-account 4.3, solana-transaction-status 4.2), so you get expected Account, found a different Account with a "multiple different versions of crate solana_" note. Pubkey is the exception: solana-pubkey 3 and 4 are the same type, so pubkeys don't trigger it.
Fix.
- Set every Carbon crate in
Cargo.tomlto2.0.0. - Set direct Solana dependencies to the versions Carbon 2.0.0 pins (for example
solana-account = "4.,3. 2" solana-instruction = "3.,4. 1" solana-pubkey = "4.,2. 1" solana-client = "=4.).2. 2" - Find the stray crate with
cargo tree -i carbon-core@1.(or0. 0 -i solana-account@3.).0. 0 - Regenerate decoders produced by an older CLI with
@sevenlabs-hq/.carbon-cli@2. 0. 0 carbon-jetstreamer-datasourceandcarbon-jito-shredstream-grpc-datasourcehave no 2.0 release; don't use them with Carbon 2.
See also. Migrate to v2, Installation.
Failed to decode transaction with Json encoding#
Error. With RpcBlockSubscribe or RpcBlockCrawler configured with UiTransactionEncoding:: or JsonParsed, every transaction logs:
ERROR carbon_rpc_block_subscribe_datasource] Failed to decode transaction: EncodedTransactionWithStatusMeta { transaction: Json(UiTransaction { … }), … }Cause. Carbon rebuilds the binary transaction with EncodedTransaction::, which only works for binary encodings. JSON payloads can't be decoded, so each transaction is skipped and no instruction processor runs.
Fix. Request a binary encoding and V1 support in the config you pass:
RpcBlockSubscribeConfig {
encoding: Some(UiTransactionEncoding::Base64),
transaction_details: Some(TransactionDetails::Full),
max_supported_transaction_version: Some(1),
..RpcBlockSubscribeConfig::default()
}Use the same fields on RpcBlockConfig for the block crawler. The transaction crawler and Helius GTFA set Base64 and V1 themselves.
See also. Stream with RPC, Migrate to v2.
Full(..) when sending updates#
Error. One of:
ERROR carbon_yellowstone_grpc_datasource] Failed to send transaction update with signature … at slot …: "Full(..)"
WARN carbon_rpc_transaction_crawler_datasource] Failed to send update: "Full(..)"
ERROR carbon_rpc_block_crawler_datasource] Error sending transaction update: "Full(..)"Cause. The pipeline's update channel is full because processors are slower than the source, and the datasource uses try_send, which drops the update instead of waiting. Yellowstone, LaserStream, Helius Atlas, RPC block subscribe, RPC block crawler, RPC program subscribe and (by default) the RPC transaction crawler all drop updates this way. Block subscribe and block crawler also stop sending the rest of that block.
Fix.
- Raise
channel_(default 1,000).buffer_ size - Make processors faster, or move slow work (database writes, HTTP calls) to a spawned task or a batch.
- For the transaction crawler, set
ConnectionConfig::to apply backpressure instead of dropping.blocking_ send = true - Watch the
carbon_gauge.updates_ queued
See also. Production, Metrics reference.
Invalid inner instruction stack height#
Error.
WARN carbon_core::transformers] invalid inner instruction stack height (None) in transaction <signature> at instruction <index>, dropping the remaining inner instructions of this groupCause. The source sent inner instructions without a stack_ (old transactions, or providers that strip it), or with a height outside 2 to 5. Carbon needs the height to rebuild the CPI tree, so it drops the rest of that instruction's inner instructions. Their instruction processors don't run.
Fix. Use a source that reports stackHeight (current RPC nodes and Yellowstone do). For historical data from before stack heights were recorded, decode inner instructions yourself from meta. in a transaction processor.
See also. Instructions.
Ctrl-C does not stop the pipeline#
Error. The process keeps running after Ctrl-C, usually under load.
Cause. Pipeline:: only listens for Ctrl-C between updates and installs a handler that replaces the default exit, so a signal that arrives while a processor runs is lost.
Fix. Handle Ctrl-C yourself and cancel a token passed to datasource_. See Ctrl-C is ignored while an update is processing.
See also. Shutdown.