Find the symptom your stream or sink shows, then work through its checks in order. Each entry names the likely cause first. If the checks do not resolve it, contact GraphOps support(opens in a new tab) with the details listed at the end of this page.
Authentication fails
The stream is missing a valid API key, or the key is sent in the wrong place.
- Confirm the key was created for the organization that owns Substreams access and includes Substreams.
- Confirm the key has not been revoked or rotated.
- Confirm you use a query key, which starts with
gqk_. Substreams refuses a service account API key (gsk_) as unauthenticated. - For the CLI and sinks, confirm
SUBSTREAMS_API_KEYis exported in the shell that runs the command. - For raw gRPC clients, confirm every stream sends
x-api-key: <GRAPHOPS_API_KEY>metadata. - Remove extra quotes or whitespace from the stored secret value.
- Compare your setup with Authentication.
Stream is refused or ends with a valid key
The gRPC status tells you which kind of problem it is:
| Status | Meaning | What to do |
|---|---|---|
UNAUTHENTICATED | The API key is missing, malformed, revoked or rotated, is not a query key, or does not include Substreams. | Work through Authentication fails. |
PERMISSION_DENIED | The key is valid, but GraphOps refuses the stream. A running stream can also end with this status, for example when credits run out. | Work through the checks below. |
UNIMPLEMENTED | The endpoint host is not a GraphOps Substreams endpoint. | Check the endpoint against Authentication. |
RESOURCE_EXHAUSTED | The organization has more streams or concurrent work open than its limits allow. | Close streams you no longer need and reduce parallel workers. See usage and limits. |
UNAVAILABLE | GraphOps could not check access right now. | Retry with backoff. |
Most refusals include the GraphOps error body, {"code", "message", "docsUrl"}, inside the status
message, sometimes after a prefix such as permission denied:. Its code names the reason, and
gateway errors and API key errors explain
each code. A new stream refused for exceeding the stream limit has no code. For
PERMISSION_DENIED:
- Check your credit balance in Billing. If it is zero or below
(
credits_exhausted), add credits to bring it above zero. Access is restored automatically. - If the balance is positive, GraphOps support may have paused the organization or disabled the key
(
usage_access_paused,organization_disabledorapi_key_disabled). Adding credits does not restore access. Contact GraphOps support(opens in a new tab), or create a new key if only the key is disabled. - For
stream_access_blocked, GraphOps blocked streaming for the organization. Contact support. - For
stream_session_key_mismatch, use the same API key for the whole stream, or start a new stream after rotating a key. - For
api_key_route_not_allowed, confirm the endpoint matches the chain you stream. - For
api_key_target_not_allowed, the key's Substreams access is limited and does not include the network of the endpoint you stream from. Stream from an allowed network, or add this one to the key's limits.
Package cannot be resolved
Standard Substreams tooling cannot load the package name, version, URL, or local .spkg reference.
- Confirm the package exists on substreams.dev(opens in a new tab) or at the URL you provided.
- Pin an exact package version rather than a moving tag such as
latest. - Confirm an unpublished
.spkgfile is readable by the process running the consumer. - Confirm the package supports the network endpoint you selected.
Module not found
The package does not expose the requested output module.
- Check the package page or manifest for the available modules.
- Match the module name exactly, including case.
- Confirm the module is a map module you can stream, not a store module.
- Regenerate client Protobuf types if the package output changed.
Stream disconnects
Long-running gRPC streams can disconnect because of network, client, or service conditions.
- Reconnect with exponential backoff and jitter.
- Resume from the latest committed cursor.
- Confirm the cursor is stored durably, not only in process memory.
- Reduce concurrency if many consumers reconnect at once.
- Log the endpoint, package reference, module name, cursor, and block number for each disconnect.
Duplicate data after reconnect
The consumer resumed from an earlier cursor, or replayed a block after a failed commit.
- Make output writes idempotent.
- Save the cursor only after the output commits.
- Store the cursor and output in one transaction when possible.
- Deduplicate by block number, block hash, ordinal, or a package-specific ID.
See Resume with cursors for the commit order.
Undo signal not handled
The stream sent a BlockUndoSignal, but the consumer did not revert its local state.
- Implement undo handling before you use reversible data for production state.
- Revert local state to the last valid block named in the signal.
- Save the signal's cursor after the rollback.
- Keep enough local history to undo recent writes.
See Cursors and reorgs for the recovery model.
Backfill is slow or expensive
The range is large, the output volume is high, or concurrency exceeds your organization's limits.
- Split the backfill into smaller ranges you can retry independently.
- Reduce concurrency.
- Use a narrower output module when possible.
- Track blocks processed, bytes out, bytes read, and bytes written.
- Check rates and limits in Usage and limits.
You need GraphOps to host the sink
Self-service Substreams assumes you run the sink. Hosted sinks are an enterprise option.
- Check whether a standard sink in your infrastructure fits; see Run a sink.
- If not, contact GraphOps from the platform about hosted sink options.
Need support
When you contact GraphOps support(opens in a new tab), include:
- Organization name or ID.
- Endpoint URL and chain ID.
- Package reference and version.
- Module name.
- Start block, stop block, and latest committed cursor.
- Approximate timestamp.
- gRPC status or error message.
- Whether the consumer saw
BlockScopedData,BlockUndoSignal, or progress messages.
Never include your API key.
Next steps
Last updated