Error handling in Snowpipe Streaming high-performance architecture¶
This topic explains Named Channel error handling for Snowpipe Streaming with high-performance architecture, including direct REST API calls. For Elastic Channel error handling, see Error handling for Elastic Channels. For REST retry delays, retryable status codes, and Named Channel recovery, see REST API error handling.
Named Channel error handling¶
Key error handling features¶
- Enhanced channel status endpoint: This edition extends the channel status endpoint to provide more comprehensive error information.
- Granular error details: The high-performance edition provides more detailed error information to help identify where it occurred and find the root causes of ingestion issues.
- Improved client experience: The high-performance edition simplifies error handling for clients, reducing the complexity of error reasoning and recovery.
- The channel history view: SNOWPIPE_STREAMING_CHANNEL_HISTORY view provides a historical record of channel activity to monitor and locate errors.
- Event table telemetry: Query events to investigate row and channel errors alongside ingestion progress and processing time. For examples and alert templates, see Monitor Snowpipe Streaming.
Channel status endpoint details¶
The high-performance architecture includes a channel status endpoint to provide more detailed, point-in-time information about a channel.
In addition to the channel status information for the classic architecture, which is statusCode, persistedOffsetToken, the high-performance architecture includes the following information:
channel_status_code: Represents the current operational status of the streaming channel. This code provides a high-level indication of the channel’s health and ability to ingest data. For more information about the channel status codes, see Client-side error handling and required actions.last_commited_offset_token: Indicates the offset token of the last row set that was successfully committed to the target table by Snowflake. This is crucial for tracking progress and ensuring data delivery.created_on_ms: The timestamp, in milliseconds, that indicates when the streaming channel was initially created within Snowflake.database_name: The name of the database to which the streaming channel is configured to ingest data.schema_name: The name of the schema within the specified database where the target table for the streaming channel resides.pipe_name: The name of the Snowpipe object that is configured to use this Snowpipe Streaming channel for data ingestion into a specific target table.channel_name: A user-created name for the specific Snowpipe Streaming channel instance.rows_inserted: A count of the total number of data rows that have been successfully inserted into the target table through this streaming channel since its creation.rows_parsed: A count of the total number of data rows that have been processed and parsed by the Snowpipe Streaming service for this channel. (but not necessarily inserted, for example, due to errors).rows_error_count: A count of the total number of data rows that encountered errors during processing and were therefore rejected by the Snowpipe Streaming service for this channel.last_error_offset_upper_bound: The upper bound of the offset token range of the last rowset (batch of rows) that contained errors. This helps in identifying the approximate location of the most recent errors within the data stream.last_error_message: A human-readable message corresponding to the latest error code.last_error_timestamp: The timestamp indicating when the most recent error occurred on this streaming channel.snowflake_avg_processing_latency_ms: The average latency, in milliseconds, observed by the Snowflake service in processing rowsets received by this channel. This metric provides insight into the performance of the ingestion pipeline within Snowflake.
Error-handling flow¶
-
Client sends data: The client application uses the Snowpipe Streaming SDK to send data to Snowflake through the
appendRow(s)API. -
Server processing: The Snowflake service processes the data. This involves:
- Buffering the data.
- Parsing and validating the data.
- Committing the data to the table.
-
Error detection: Errors can occur during any of the server-side processing stages.
-
Error recording: Snowflake records detailed information about the last error that occurred, including the following information:
- The upper bound of the offset token range of the last rowset that contained errors. This helps in identifying the approximate location of the most recent errors within the data stream.
- An error message.
- A timestamp.
-
Error reporting:
- The enhanced channel status endpoint provides access to the recorded error information.
- Clients can query this endpoint to retrieve details about the last error that occurred.
- SNOWPIPE_STREAMING_CHANNEL_HISTORY view provides a historical record of errors and their offsets.
-
Client action: The client application uses the error information to perform the following actions:
- Identify the cause of the error.
- Implement appropriate error handling logic, such as the following actions:
- Retrying the failed operation.
- Logging the error.
- Alerting an administrator.
- Moving the erroneous data to a dead-letter queue.
- Reopening channels.
Client-side error handling and required actions¶
The Snowpipe Streaming SDK simplifies error handling by implementing internal retry logic for transient errors. However, for fatal channel errors and persistent authorization issues, you are required to take manual action.
SDK retry logic for transient errors¶
The SDK automatically retries the request to send unflushed data in the channel to the server for the following HTTP status codes, as they typically indicate a temporary or transient service issue:
- 5XX (Server errors)
- 429 (Too many requests)
- 408 (Request timeout)
Channel errors that require a manual reopen¶
The Snowpipe Streaming SDK doesn’t automatically reopen the channel. When a channel enters a state that isn’t valid, you must explicitly close and reopen the channel to continue ingestion.
A channel is considered invalid — and requires client action — if the channel_status_code in the channel status response is anything other than SUCCESS.
The following table shows persisted error codes that indicate a fatal channel state and require the channel to be reopened:
| Error code | Context | Required client action |
|---|---|---|
| ERR_PIPE_DOES_NOT_EXIST_OR_NOT_AUTHORIZED | The target pipe is missing or inaccessible. | Fix the pipe issue. Reopen channel. |
| ERR_TABLE_DOES_NOT_EXIST_NOT_AUTHORIZED | The target table is missing or inaccessible. | Fix the table issue. Reopen channel. |
| ERR_CHANNEL_HAS_INVALID_ROW_SEQUENCER | Row sequencing state isn’t valid. | Reopen channel. |
| ERR_CHANNEL_HAS_INVALID_CLIENT_SEQUENCER | Channel sequencing state isn’t valid. | Reopen channel. |
| ERR_CHANNEL_MUST_BE_REOPENED | A general error indicating the channel is unusable. | Reopen channel. |
| ERR_CHANNEL_MUST_BE_REOPENED_DUE_TO_ROW_SEQ_GAP | A gap in the row sequence was detected. | Reopen channel. |
Schema evolution failure and channel invalidation¶
When you use the Snowpipe Streaming high-performance architecture, it is important for you to understand a specific exception to the general ON_ERROR=CONTINUE behavior regarding schema evolution.
Channel invalidation on schema errors¶
Even if the ON_ERROR=CONTINUE option is configured for the load, the channel is invalidated if it encounters a schema evolution failure caused by user errors.
The following list includes common user errors that trigger channel invalidation:
- Submitting data with invalid column names that can’t be mapped.
- Attempting to add more columns than allowed by the configured column limit in a single batch. When columns are added across multiple batches, there is no limit.
This channel invalidation prevents the pipe from continuing to accept data that would cause persistent, non-recoverable schema issues. You can verify the invalidation status and reason for the channel failure by calling the getChannelStatus() method. For more information about the channel status fields, see Channel status endpoint details.
Authorization errors that require a configuration fix¶
When an ingestion attempt results in an HTTP authorization error, you must correct the underlying permission or credential issue. Don’t reopen the channel for these errors because the new channel immediately encounters the same problem.
- 401 (Unauthorized)
- 403 (Forbidden)
For these errors, stop the ingestion, and then fix the client application’s security configuration — for example, pipe permissions, user role, authentication credentials — before you resume ingestion. After you fix the authorization issue, you can reopen the client to continue ingestion.
Handling SDK exceptions and HTTP status codes¶
When you use the Java SDK, methods such as appendRow, appendRows, getLatestCommittedOffsetToken, and getChannelStatus might throw an SFException. To ensure resilient ingestion, applications must catch these exceptions, and then inspect getHttpStatusCode() to determine the required recovery action.
The following table describes common HTTP status codes, their error conditions, and the required actions:
| Status code | Error condition | Required action |
|---|---|---|
| 409 | Channel invalidated | The channel is no longer valid; for example, superseded by another client. Close the current channel, call openChannel to create a new instance, and then resume from the last committed offset. |
| 429 | Throttling | The client is sending data too quickly. Implement an exponential backoff and retry strategy. |
| 500 / 503 | Service error | Transient network or server-side issues. These errors are typically retryable after a short delay. |
| 401 | Unauthorized | Authentication failed. Verify credentials, JWT configuration, or role permissions. |
Understanding invalidation levels¶
It is critical to distinguish between a channel invalidation and a client invalidation:
- InvalidChannelException (HTTP 409): Only the specific channel is affected. Reopening the channel is sufficient.
- InvalidClientException: The entire
SnowflakeStreamingIngestClientis compromised. You must close the existing client, initialize a new one using the factory, and then reopen all associated channels.
REST API error handling¶
Direct REST clients implement retries in their own HTTP client. SDK clients continue to use the retry and reopen behavior earlier in this topic. For endpoint paths, headers, and request fields, see Snowpipe Streaming REST API endpoints.
A request that doesn’t meet the client requirements returns an HTTP 4xx error. These errors generally aren’t retryable, except for the cases in Retry policy.
Retry policy¶
If a request fails with a retryable response, retry it with exponential backoff and jitter.
Cap the total retry time at 1 hour. When the retry time is exhausted, stop, return the error to your application, and alert an operator.
Treat these responses as retryable:
- HTTP 404, only when the response
Content-Typeis HTML, or when theContent-Typeis JSON and bothcodeandmessageare empty. A 404 with a payload that matches the error response structure isn’t retryable. - HTTP 408
- HTTP 429
- HTTP 499
- All HTTP 5xx responses
For HTTP 401 or 403 responses caused by authentication, renew the token and retry the request. If the role isn’t authorized for the pipe or table, fix the privileges before you retry. A permissions failure repeats until the role can access those objects.
Recover a Named Channel after a REST error¶
This procedure applies to Named Channels, which support channel lifecycle, continuation tokens, and offset-based recovery. It doesn’t apply to Elastic Channels. For Elastic append retries, see Error handling for Elastic Channels.
- Stop sending requests on the current channel instance. Don’t call Drop Channel, because it removes the channel state and metadata that recovery depends on.
- Reopen the same channel with the Open a Named Channel operation, with
fail_on_uncommitted_rowsset totrue. If the open fails with HTTP 409, check the error code:ERR_OPEN_CHANNEL_IN_PROGRESS: Retry for up to 2 minutes, using the retry policy. If retries are exhausted, stop overlapping open requests for that channel and return the error to your application. Opening withfail_on_uncommitted_rowsset tofalsedoesn’t resolve an open that’s already in progress.ERR_CHANNEL_HAS_UNCOMMITTED_DATA: Retry for up to 2 minutes, using the retry policy. If retries are exhausted, reopen once more withfail_on_uncommitted_rowsset tofalse. This discards the in-flight data.
- After a successful open:
- Read
last_committed_offset_tokenandnext_continuation_tokendirectly from the open-channel response. Storelast_committed_offset_tokenfor recovery and usenext_continuation_tokenfor the next append. Don’t call the channel-status API immediately after opening the channel to discover these values. - Read
next_continuation_tokenfrom each successful append response, and use that value for the next append request.
- Read
- Resume ingestion with the first uncommitted record after
last_committed_offset_token. For example, if the returned Kafka offset is20, resume at offset21, not20. Snowflake stores source offsets but doesn’t use them to prevent re-ingestion, so replaying the committed record can create a duplicate. For more information, see Offset tokens and exactly-once delivery.- If
last_committed_offset_tokenisnull, resume from the source position retained by your application.
- If
Row-level error logging¶
For row-level error debugging, turn on error logging on your target table. When turned on, rows that fail during server-side processing are automatically captured in a dedicated error table.
For more information, see Error logging in Snowpipe Streaming with high-performance architecture.