SFTP Data Connector
The BigPanda Secure File Transfer Protocol (SFTP) data connector ingests file-based data from SFTP servers into the Unified Data Connector (UDC) pipeline. It supports configurable incremental sync strategies, streaming CSV reads with retries on transient failures, and chunked writes for large files. It can also stream matched CSV files directly to Amazon S3 as size-bounded JSON Lines (JSONL), keeping only the rows updated on or after each file's date within a configurable look-back window.
Key features
Scheduled file ingestion from SFTP servers via cron expressions.
Configurable fallback behavior for files with unparseable filename dates.
Streaming CSV reads with automatic retry on transient SFTP failures.
Progress logging and chunked writes for large files.
Direct-to-S3 streaming that filters each file to the rows updated on or after its filename date, within a configurable look-back window, and writes size-bounded JSONL objects to Amazon S3.
Read resilience and streaming
The SFTP connector streams CSV rows as it reads each file rather than buffering the entire file in memory, and automatically retries transient read failures.
Append mode
Because retries restart the file from the beginning, rows emitted before a mid-file failure may be re-emitted after a successful retry. In append-mode pipelines, this can introduce duplicate rows for the affected file. Use a downstream deduplication step or prefer replace-mode loads when duplicates are not acceptable.
Streaming CSV reads. CSV files are streamed row-by-row rather than fully loaded into memory before processing. During a read, the connector logs the file size before the read starts and a row-progress counter every 1,000 rows processed. Use these logs to monitor ingestion progress for large files.
Chunked writes. SFTP pipelines apply connector-scoped chunking limits so that load packages flush in smaller batches. For very large input files, this means the downstream loader can start processing data before the entire source file has been read, improving end-to-end throughput.
Resume after restart
Chunk resume state is persisted to S3 rather than local run disk, so progress survives a replaced run environment (for example, a pod restart) rather than restarting large files from the beginning.
By default, historical (mode: historical) runs clear chunk resume progress before reading files. Two options change this behavior:
Option | Description |
| When |
| Seeds a starting byte offset for an interrupted historical CSV load. Remove this value after the file reaches EOF. |
Plan changes during a maintenance window
Use preserve_chunk_resume or chunk_resume_seed when recovering an interrupted historical load. Validate the resumed byte offset and row counts after the run completes.
Authentication
The SFTP connector uses SSH key authentication. These details are required when configuring the connection:
Instance URL: SFTP host (for example,
sftp://sftp.example.comorsftp.example.com).Username: SFTP username.
Private key: PEM-encoded private key (RSA, Ed25519, or ECDSA).
Passphrase: Optional; for encrypted private keys.
Sync preferences
Provide the following information about your sync preferences to BigPanda:
Required Configuration
Option | Description |
|---|---|
| Cron expression for scheduling the connector (for example, |
Optional Pipeline Configuration
Option | Description |
|---|---|
| Start date for data collection in We recommend syncing 12 months of data. |
| Controls how the SFTP connector tracks progress during incremental syncs. You can choose one of three strategies.
Tip Remapping and incremental sync When you set |
| Fallback behavior when filename dates are unparseable. Only applies when
|
| Remaps incoming file rows before they are loaded. When unset, rows are loaded in their raw source-file shape as source columns into the
For all ServiceNow-style shapes, choice mappings accept either the |
| Applies only when |
| Applies only when |
| Overrides the destination resource name that the connector loads into. When unset, the destination defaults to |
| Selects how matched files are ingested. See Direct-to-S3 streaming below. Connectors that omit |
Fallback strategy best practice
Start with mtime_fallback during initial setup to avoid pipeline failures from unexpected filenames. Switch to skip or fail once you have validated that all source files follow a consistent naming convention.
Use caution during this process. Switching between incremental strategies on an existing pipeline may cause files to be reprocessed or skipped, depending on the difference between filename dates and file modification times. Plan strategy changes during a maintenance window.
Output remapping and destination resources
By default, the SFTP connector loads each file's rows in their raw source-file shape as source columns into the sftp_files resource. Set row_format to remap exports before they are loaded:
itmapp_servicenoworitmapp_servicenow_incidentmaps incident-shaped rows.itmapp_servicenow_cmdb_cimaps configuration-item-shaped rows.itmapp_servicenow_change_requestmaps change-request-shaped rows.itmapp_servicenow_problemmaps problem-shaped rows.itmapp_servicenow_kb_knowledgemaps knowledge-article-shaped rows.itmapp_flatmaps a flat ITMAPP passthrough, keeping every column as plain text withsys_idaliased fromflat_sys_id_source.
The destination resource the connector loads into depends on your configuration:
No
row_format: Loads target thesftp_filesresource.Incident remapping: Loads default to the
incidentresource.Configuration-item remapping: Loads default to the
cmdb_ciresource.Change-request remapping: Loads default to the
change_requestresource.Problem remapping: Loads default to the
problemresource.Knowledge-article remapping: Loads default to the
kb_knowledgeresource.dlt_resource_nameset: Loads target the resource name you provide, overriding the defaults above.
Remapped SFTP loads
If you enable row_format on an existing SFTP pipeline, the destination resource changes from sftp_files to the remapped resource (incident, cmdb_ci, or the itmapp_flat destination), or to the value of dlt_resource_name. Because cursor state follows the effective resource name, an existing pipeline's tracked progress does not carry over to the new resource.
Plan changes during a maintenance window
Enabling or changing row_format or dlt_resource_name on an existing pipeline changes the destination resource and the resource that cursor state is tracked against. This may cause data to load into a different resource than before, or progress to be re-tracked from the start. Plan these changes during a maintenance window, and validate the destination resource and incremental progress after the change.
Direct-to-S3 streaming
Set upload_mode to direct_s3 to stream a matched CSV file directly to Amazon S3 as JSON Lines (JSONL), keeping only rows updated on or after the date in the filename.
This mode is recommended when you receive a full CSV snapshot each day and want to land only that day's updates in object storage instead of loading the entire snapshot through the pipeline.
upload_mode accepts three values:
parse: Loads matched files through the normal pipeline. This is the default, and connectors that omitupload_modekeep this behavior.raw_copy: Copies matched files byte-for-byte.direct_s3: Streams matched CSV files to S3 as JSONL with date-based row filtering.
Defaults changed for existing direct_s3 connectors
A direct_s3 connector that does not set direct_row_lookback_days or direct_shard_max_rows adopts the one-day look-back window and the 100-row shard default on its next run. This can keep more rows and produce more, smaller output objects than before. Set these keys explicitly to keep the earlier behavior. parse and raw_copy connectors are unchanged.
Direct-to-S3 requirements
When you set upload_mode to direct_s3, the connector validates the rest of the configuration before a run and stops with an error if any of the following is not true:
file_formatiscsv.incremental_byisfilename_date.sys_updated_columnis set and non-empty.The destination is S3-backed.
row_date_columnis cleared, because the filename-date filter replaces it.modeishistoricalorincremental.If
filter_date_overrideis set, it is a full ISO date inYYYY-MM-DDformat. Trailing characters are rejected.
Row filtering
direct_s3 keeps a row when the value in sys_updated_column is on or after the start of the file's filename date in UTC (or the filter_date_override date, when one is set), minus the look-back window set by direct_row_lookback_days. sys_updated_column defaults to sys_updated_on. Rows with a missing or unparseable value in that column are dropped.
direct_row_lookback_days defaults to 1. By default, the connector also keeps prior-day updates that arrived after that day's export, for example, late updates that missed an early-morning snapshot cutoff. Set direct_row_lookback_days to 0 for a strict same-day cutoff, or to a higher value to widen the window.
Pin a date with filter_date_override
Without an override, direct_s3 tracks progress by filename date. It keeps that filename-date cursor in a dedicated resource separate from your data, so the cursor does not appear in the {dataset}/{resource} output folder.
Set filter_date_override to a full ISO date (YYYY-MM-DD) to ingest exactly the one file whose filename date matches that day, with the row cutoff pinned to the same date. After that file is ingested successfully, the override advances to the next day. If the file for that day is not present, nothing is ingested, and the override stays in place, so the next run retries the same day.
When filter_date_override is set, it is the only watermark the connector uses. The filename-date cursor is neither read nor written while an override is in effect.
If filter_date_override is two or more days ahead of today in UTC, the run fails with an error prompting you to reset the override to a valid date, rather than waiting for a file that does not yet exist.
Re-ingesting a day is safe in override mode
When filter_date_override is set, output object keys are pinned to the filter date, so re-ingesting a day overwrites the same objects instead of creating duplicates. Without an override, object keys use the run start time, so a retry writes new objects.
Output layout and sharding
Each JSONL object is finalized when it reaches direct_shard_max_rows (default 100 rows) or direct_shard_max_bytes (default 10,485,760 bytes, 10 MiB), whichever comes first. Objects follow the same filesystem and S3 JSONL layout used elsewhere:
{dataset}/{resource}/{YYYY}/{MM}/{DD}/{HH}-{mm}/{load_id}.{shard}.jsonl
Tune shard size
The default of 100 rows per object produces many small JSONL objects, allowing downstream jobs to start processing before the file ends. If your consumers prefer fewer, larger files, raise direct_shard_max_rows. The 10 MiB byte cap always applies.
Remapping in direct_s3
Within direct_s3, row_format accepts raw (the default passthrough) or itmapp_flat. Other ServiceNow object-shape remaps are rejected in this mode. As on the parse path, itmapp_flat still requires flat_sys_id_source.
Pre-load redaction is not supported
direct_s3 bypasses the pipeline data load and cannot apply pre-load redaction. If pre-load redaction is configured for the connector, direct_s3 fails to start. Use upload_mode: parse when redaction is required.
direct_s3 Configuration options
Option | Description |
|---|---|
sys_updated_column | Names the CSV column that holds each row's last-updated timestamp. |
filter_date_override | Optional. A full ISO date ( |
direct_row_lookback_days | Number of days before the file's filename date (or |
direct_shard_max_rows | Maximum number of rows per output JSONL object before it is finalized. Defaults to 100. Raise this for fewer, larger objects. |
direct_shard_max_bytes | Maximum size in bytes per output JSONL object before it is finalized. Defaults to 10,485,760 (10 MiB). |
Validation and troubleshooting
If a direct_s3 run stops before ingesting, check configuration settings. Common causes:
CSV required:
direct_s3only reads CSV files. Confirmfile_formatiscsv.Filename-date tracking required: Confirm
incremental_byisfilename_dateand thatrow_date_columnis cleared.Missing timestamp column: Confirm
sys_updated_columnis set and names a real column in the file. Rows with a missing or unparseable value in that column are dropped.Bad override value:
filter_date_overridemust be a full ISO date (YYYY-MM-DD) with no trailing characters.Override too far ahead: If
filter_date_overrideis two or more days ahead of today (UTC), the run fails. Reset it to a valid date, typically today or yesterday.Redaction configured:
direct_s3fails to start when pre-load redaction is configured. Useupload_mode: parseinstead.
A large number of small JSONL objects is expected with the default direct_shard_max_rows of 100, and it is not an error. Raise direct_shard_max_rows if you want fewer, larger objects.