Symptom
Files are arriving in the stage location, but the target table is not growing. Nobody gets an error, because Snowpipe runs in the background and, by default, skips bad files (ON_ERROR = SKIP_FILE) instead of failing loudly.
Work through three questions in order:
- Is the pipe running?
- Is Snowflake receiving the file notifications?
- Did the files load, fail, or get skipped?
1. Is the pipe running?
SELECT SYSTEM$PIPE_STATUS('raw.sales.orders_pipe');
The function returns JSON. Pull out the fields you need:
SELECT PARSE_JSON(SYSTEM$PIPE_STATUS('raw.sales.orders_pipe')) AS s,
s:executionState::string AS state,
s:pendingFileCount::int AS pending_files,
s:lastReceivedMessageTimestamp::string AS last_msg,
s:lastForwardedMessageTimestamp::string AS last_forwarded,
s:lastIngestedTimestamp::string AS last_ingested,
s:error::string AS error;
Fields only appear when they apply, so a missing field is normal.
executionState | What it means | Fix |
|---|---|---|
RUNNING | The pipe is healthy. It may or may not be loading at this moment | Go to step 2 |
PAUSED | Someone paused it, or ownership was transferred | Resume it (below) |
STOPPED_CLONED | The pipe sits in a cloned database or schema | Expected in clones. In the source, check the original pipe |
STOPPED_STAGE_ALTERED / STOPPED_STAGE_DROPPED | The stage behind the pipe changed or was dropped | Recreate the stage, then recreate the pipe |
STOPPED_MISSING_TABLE | The target table was dropped | Recreate or undrop the table, then recreate the pipe |
STOPPED_FILE_FORMAT_DROPPED | The named file format is gone | Recreate the file format |
STOPPED_NOTIFICATION_INTEGRATION_DROPPED | The notification integration (Azure/GCP) is gone | Recreate the integration and the pipe |
STALLED_COMPILATION_ERROR | The pipe's COPY statement no longer compiles, usually because a column was renamed or dropped | Check invalid_reason in SHOW PIPES or DESC PIPE |
STALLED_STAGE_PERMISSION_ERROR | Snowflake cannot read the external location | Fix the storage integration or the IAM role / RBAC grant on the bucket or container |
READ_ONLY | The pipe is in a secondary (replica) database | Expected until the database is promoted |
SHOW PIPES LIKE 'orders_pipe' IN SCHEMA raw.sales;
DESC PIPE raw.sales.orders_pipe; -- definition, notification_channel, invalid_reason
Resume a paused pipe
ALTER PIPE raw.sales.orders_pipe SET PIPE_EXECUTION_PAUSED = FALSE;
If the pipe changed owner while paused, or was paused for longer than the 14-day message retention period, a plain resume is not enough:
-- Ownership changed while paused
SELECT SYSTEM$PIPE_FORCE_RESUME('raw.sales.orders_pipe');
-- Paused for more than 14 days (auto-ingest pipes)
SELECT SYSTEM$PIPE_FORCE_RESUME('raw.sales.orders_pipe', 'STALENESS_CHECK_OVERRIDE');
Warning
After a stale resume, Snowflake processes notifications older than 14 days on a best-effort basis only. Assume some files were missed and backfill them (section 4).
2. Is Snowflake receiving notifications?
The state is RUNNING but nothing is loading. Compare the timestamps from step 1:
lastReceivedMessageTimestampis old or missing. Event notifications are not reaching Snowflake. The problem is on the cloud side.- Received is recent, but
lastForwardedMessageTimestampis old. Messages arrive but do not match the pipe. The usual cause is a path that doesn't match the stage URL or prefix, or the wrong case in a path. - Forwarded is recent, but nothing is ingested. The files are reaching COPY. Go to step 3.
Amazon S3
The pipe's SQS queue ARN is in the notification_channel column of SHOW PIPES. Check that the bucket's event notification sends s3:ObjectCreated:* to that ARN, and that the prefix filter matches the stage path:
aws s3api get-bucket-notification-configuration --bucket my-landing-bucket
A common cause is a second tool, such as Terraform or another team's Lambda trigger, overwriting the bucket's notification configuration. S3 keeps one notification configuration per bucket, and each put-bucket-notification-configuration call replaces it completely.
Azure Blob / ADLS Gen2
Check that the Event Grid subscription still exists, filters on Microsoft.Storage.BlobCreated, and delivers to the storage queue named in the notification integration:
az eventgrid event-subscription list \
--source-resource-id $(az storage account show -n mylandingacct -g rg-data --query id -o tsv) \
-o table
DESC NOTIFICATION INTEGRATION azure_snowpipe_int;
If the Snowflake service principal lost its role on the queue (Storage Queue Data Contributor) or on the container, notifications stop or files can't be read.
3. Did the files load, fail or get skipped?
SELECT file_name, status, row_count, row_parsed, error_count,
first_error_message, first_error_line_number, first_error_column_name,
pipe_received_time, last_load_time
FROM TABLE(information_schema.copy_history(
TABLE_NAME => 'RAW.SALES.ORDERS',
START_TIME => DATEADD('hour', -24, CURRENT_TIMESTAMP())))
ORDER BY pipe_received_time DESC;
This table function covers the last 14 days. For longer history, query SNOWFLAKE.ACCOUNT_USAGE.COPY_HISTORY, which can lag by up to a couple of hours.
To see the errors Snowpipe hit for a pipe:
SELECT *
FROM TABLE(information_schema.validate_pipe_load(
PIPE_NAME => 'raw.sales.orders_pipe',
START_TIME => DATEADD('hour', -24, CURRENT_TIMESTAMP())));
| What you see | Cause | Fix |
|---|---|---|
status = 'Load failed', a parsing error | File format mismatch: delimiter, header, quoting or compression | Fix the file format, then reload (section 4) |
Partially loaded | ON_ERROR = CONTINUE let bad rows through | Decide whether partial data is acceptable, then fix the source |
| Error on a column count or a type | The upstream schema changed | Fix the target table or the COPY transform, then recreate the pipe |
| The file is missing from COPY_HISTORY entirely | No notification, a path mismatch, or the file was already loaded under the same name | Step 2. To reload a file that was already loaded, rename it in storage |
| Loaded, but the table is still empty | The COPY loads into a different table, or downstream tasks/streams aren't running | Check the pipe definition with DESC PIPE |
Confirm what is actually in the stage:
LIST @raw.sales.orders_stage/2026/10/26/;
4. Reload the gap safely
Once the cause is fixed, queue the missed files:
ALTER PIPE raw.sales.orders_pipe REFRESH
PREFIX = '2026/10/26/'
MODIFIED_AFTER = '2026-10-26T00:00:00Z';
REFRESH only sees files staged within the last 7 days. It checks the load history of both the pipe and the table, so files that are already loaded are skipped. For files older than 7 days, run a one-off COPY INTO with PATTERN or FILES. COPY also skips files recorded in the table's load metadata unless you set FORCE = TRUE.
COPY INTO raw.sales.orders
FROM @raw.sales.orders_stage/2026/10/15/
FILE_FORMAT = (FORMAT_NAME = raw.sales.csv_fmt)
ON_ERROR = ABORT_STATEMENT;
Caution
CREATE OR REPLACE PIPEdrops the pipe's load history. A broadREFRESHstraight afterwards can queue files the old pipe already loaded. Check COPY_HISTORY first, keepPREFIXandMODIFIED_AFTERtight, and never useFORCE = TRUEon a range that was partly loaded. If you do, you will load duplicates.
To change a pipe's COPY statement, pause the pipe, wait for pendingFileCount to reach 0, recreate the pipe, then resume it and refresh only the window where files may have been missed.
Prevent it next time
- Alert on freshness, not just failures. Schedule a task or an external check that compares
lastIngestedTimestamp, orMAX(last_load_time)from COPY_HISTORY, against the expected arrival interval. - Alert on
Load failedrows inACCOUNT_USAGE.COPY_HISTORYevery hour. - Own the bucket notification in one place. Manage S3 event notifications or Event Grid subscriptions in the same IaC module as the pipe, so no other tool can overwrite them.
- Treat schema changes as pipe changes. Renaming a table column can stall the pipe. Include
SYSTEM$PIPE_STATUSchecks in the deployment's smoke test. - Never reuse file names for corrected files. Write them with a new name so Snowpipe picks them up.
- Track Snowpipe cost and volume in
SNOWFLAKE.ACCOUNT_USAGE.PIPE_USAGE_HISTORY. A sudden drop in files or bytes is an early warning that ingestion has stopped.