Your Fabric pipeline ran twice in the same window — no error, no warning, no failed run in the monitoring tab. Just duplicated rows in your fact table.

THE SETUP THAT CAUSES IT

You have a scheduled trigger running every 15 minutes AND a tumbling window trigger (or a second schedule) on the same pipeline for "catch-up" or backfill purposes. Both are active. Both are valid. Both fire independently.

Fabric does not check whether a previous run of the same pipeline is still in progress before starting a new one. Unless you explicitly configure concurrency control, overlapping runs are allowed by design.

WHAT THIS LOOKS LIKE IN PRODUCTION

Run 1 starts at 10:00, still processing a slow source query at 10:15.
Run 2 starts at 10:15 as scheduled — same pipeline, same destination table, same time window.
Both complete "successfully." Monitoring shows two green checkmarks. Your fact table now has the same batch loaded twice.

THE FIX

In the pipeline's trigger settings, set Concurrency to 1 on any trigger where overlapping runs would cause duplication. This is not the default — it has to be set explicitly per trigger.

For tumbling window triggers specifically, use the "Max concurrency" property and set dependency conditions so a new window won't fire until the prior one's status is finished.

If your load logic isn't idempotent (i.e., re-running the same batch produces different results), add a run-lock check at the start of the pipeline: query an audit/watermark table for an "in progress" flag before proceeding.

THE LESSON

Two green checkmarks in monitoring does not mean everything ran correctly once. It means everything ran without throwing an error — which is not the same thing. Always check for overlapping run windows, especially on any pipeline with more than one active trigger.