I Tried to Build a Self-Healing Data Pipeline. It Healed the Wrong Things.

Written by anushakovi | Published 2026/04/02
Tech Story Tags: data-pipelines | self-healing-data-pipelines | data-governance | data-engineering | data-quality | ai-analytics | software-architecture | data-observability

TLDRA company's self-healing pipeline failed to detect and fix a data quality issue. The pipeline was supposed to skip the malformed records, log the issue, continue processing the rest, and send an alert to the engineering Slack channel. The "malformed records" it skipped were 23% of the day's transactions, but the pipeline continued processing the remaining 77%.via the TL;DR App

The pipeline restarted itself perfectly. It also silently served bad data for six hours.

I'll tell you the exact moment I stopped trusting our self-healing pipeline.

It was a Tuesday. A source system changed a column from VARCHAR to INTEGER without telling us. Our pipeline detected the schema mismatch, caught the error, retried three times (as configured), then fell back to the recovery logic we'd built: skip the malformed records, log the issue, continue processing the rest, and send an alert to the engineering Slack channel.

By every definition of "self-healing," the pipeline worked. It didn't crash. It didn't require manual intervention. It recovered autonomously. It even sent us a polite notification.

The problem: the "malformed records" it skipped were 23% of the day's transactions. The pipeline continued processing the remaining 77% and loaded them into the warehouse. The dashboards have been updated. The metrics looked plausible. Revenue was a little lower than expected, but it was a Tuesday, so nobody questioned it.

We didn't discover the gap until Thursday, when finance ran their reconciliation and found a $1.2M discrepancy. By then, two days of reports had gone to leadership, a marketing team had adjusted their weekly budget allocation based on the incomplete numbers, and an AI-powered analytics query had told a product manager that engagement was "trending down" when it was actually stable.

The pipeline healed itself. The data governance did not.

What "Self-Healing" Actually Means (and Doesn't)

Most of what the industry calls self-healing falls into three categories.

Infrastructure healing: the pipeline detects a resource constraint (memory, compute, network) and automatically scales, restarts, or retries. This is the most mature category. Kubernetes does it. Spark does it. Airflow's retry logic does it. It's real, it works, and it solves infrastructure problems well.

Schema healing: the pipeline detects a schema change (new column, changed type, dropped field) and adapts. This is harder. Some tools handle additive changes well (new columns get ignored or auto-added). Breaking changes (type changes, dropped required fields) are much harder to heal automatically because the "fix" depends on business context that the pipeline doesn't have.

Data quality healing: the pipeline detects a quality issue (unexpected nulls, values outside expected ranges, duplicates) and corrects it. This is where things get dangerous, because "correcting" a data quality issue requires understanding what the data should look like, and that understanding is a governance decision, not an engineering decision.

The Tuesday incident was a data quality healing attempt. The pipeline detected bad records and removed them. That's a reasonable engineering response. But the governance response should have been different: stop processing, notify the data consumers that today's data is incomplete, and wait for a human to decide whether to proceed with partial data or delay until the source system is fixed.

The pipeline didn't know which response was appropriate because nobody had told it. We'd built the healing logic for resilience. We hadn't built it for trust.

What I Actually Built

Let me walk through the self-healing system we designed, what worked, what didn't, and what I rebuilt after the Tuesday incident.

The Original Architecture

Our pipeline ingested data from six source systems into a Snowflake warehouse via Airflow. The self-healing layer had three components.

Retry logic: any task that failed got three retries with exponential backoff. Transient failures (network timeouts, temporary permission errors, throttled API responses) resolved themselves 90% of the time. This was the best part of the system and the least controversial.

Schema drift handling: We used a schema registry that compared incoming data against the expected schema before loading. Additive changes (new columns) were auto-absorbed. Breaking changes triggered a fallback mode that loaded the data into a quarantine table and alerted the team. In theory, this prevented bad data from entering the warehouse. In practice, the quarantine table was checked inconsistently and sometimes not for days.

Quality circuit breakers: we defined thresholds for key quality signals. If the null rate exceeded 5% on a critical column, or if the row count deviated more than 30% from the seven-day average, the pipeline would flag the batch. The flag was supposed to pause the load and wait for human review. What it actually did, due to a configuration I'm embarrassed to admit, was log the flag and continue loading. The "pause" was a log message, not an action.

Where It Worked

Infrastructure healing was genuinely valuable. Over six months, the retry logic resolved 847 task failures without human intervention. These were almost entirely transient issues: a source API that timed out, a warehouse connection that dropped, a temporary permissions error after a credential rotation. Without the retry logic, each of these would have been a manual restart, probably at an inconvenient hour. That's real value.

Schema drift handling caught three breaking changes before they reached the warehouse. In each case, the quarantine mechanism worked as designed, and the engineering team was able to assess the change and update the pipeline within a few hours. The schema registry paid for its complexity in the first month.

Where It Failed

Quality circuit breakers were the failure point, and the failure wasn't technical. It was philosophical.

When the pipeline detected a quality issue, it had three possible responses: stop and wait for a human, continue with degraded data, or attempt to fix the data automatically. We chose option two (continue with degraded data) because stopping the pipeline meant no data for downstream consumers, and the business had made it clear that late data was worse than imperfect data.

That's a governance decision. And it was the wrong one for the specific failure we encountered, but it was the right one for the failures we'd been imagining when we designed the system (minor null rate increases, small row count deviations). The problem is that a quality threshold doesn't know the difference between "2% of records have a null email address" and "23% of records are missing entirely because a source system changed its schema." Both trigger the same circuit breaker. The pipeline treats them the same. But one is a minor quality issue, and the other is a data completeness crisis.

Self-healing systems treat all failures as engineering problems. Some failures are governance problems. The healing logic can't tell the difference without the business context that it doesn't have.

What I Rebuilt

After the Tuesday incident, I redesigned the quality circuit breakers around three principles.

Severity Tiers, Not Binary Thresholds

Instead of a single threshold that either flags or doesn't, I created three severity tiers. Tier 1 (cosmetic): null rate on non-critical fields exceeds the baseline by a small margin. Action: log it, continue loading, include a data quality note in the dashboard metadata. No human intervention needed. Tier 2 (material): row count deviates more than 15% from the rolling average, or the null rate on a critical field exceeds the threshold. Action: load the data but mark the batch as "degraded" in the table metadata. Downstream dashboards show a warning banner. AI agents that query the table receive a metadata flag indicating the data may be incomplete. Notify the data team on Slack. Tier 3 (critical): row count drops more than 30%, a primary key has duplicates, or a schema-breaking change is detected that the quarantine system can't resolve. Action: stop the pipeline. Do not load the data. Notify the data team and the affected business teams. The dashboard shows "data unavailable" rather than showing incomplete numbers that look plausible.

The key change: Tier 3 stops the pipeline even though the business said they'd rather have late data than no data. After the Tuesday incident, I went back to the stakeholders with a specific question: "Would you rather see a dashboard that says 'data unavailable, estimated resolution by 2 pm' or a dashboard that shows numbers that are silently 23% low?" Every single person chose the first option. The original "always continue" policy was based on a hypothetical conversation. The new policy was based on a real failure.

Machine-Readable Healing Status

Every batch that loads into the warehouse now carries metadata: a healing_status field that indicates whether the batch is "clean," "degraded," or "healed with caveats." The caveats field is a structured description of what happened: "12 records skipped due to schema mismatch in column X" or "row count 18% below seven-day average, possible source system delay."

This metadata is queryable. A BI tool can check it before rendering a dashboard. An AI agent can check it before returning an answer. A data quality report can aggregate it to show healing frequency by source system over time.

Before this change, our self-healing was invisible. The pipeline healed, but nobody downstream knew it had healed, or what it had healed away. Now the healing is transparent. The data says: "I'm here, but here's what happened on the way in."

Governance-Aware Healing Policies

Different tables now have different healing policies based on their governance classification. Financial tables (anything that feeds board reports, investor metrics, or compliance reporting) have the strictest policy: any material quality issue stops the pipeline. No automatic continuation. No "skip the bad records." If the finance data is incomplete, the system waits for a human. Operational tables (anything that feeds internal dashboards or team-level metrics) have a moderate policy: degrade gracefully but flag aggressively. Load the data, mark it as degraded, and ensure downstream consumers see the warning. Experimental tables (anything used for ad hoc analysis, ML features, or exploratory work) have a permissive policy: retry, skip bad records, continue processing, log everything. Speed matters more than completeness for these use cases.

This classification was the missing piece. A self-healing pipeline that treats every table the same is a pipeline that doesn't understand governance. Financial data and experimental data have different tolerances for error, different downstream consequences, and different stakeholder expectations. The healing logic should reflect that.

The Scorecard

Healing Type

Before Rebuild

After Rebuild

Infrastructure (retries, scaling)

Worked well, 90% auto-resolution

Unchanged, still effective

Schema drift

Caught breaking changes, quarantine worked

Added automated notifications to affected consumers

Quality (cosmetic)

Logged and continued silently

Logged, continued, added metadata flag

Quality (material)

Logged and continued silently

Loaded as degraded, dashboard warnings, team notified

Quality (critical)

Logged and continued silently

Pipeline stopped, stakeholders notified, dashboard shows "unavailable"

What I Learned That I Didn't Expect

Self-healing pipelines optimize for uptime. Governance optimizes for trust. These are not the same thing. A pipeline that never goes down but sometimes serves incomplete data has perfect uptime and imperfect trust. A pipeline that occasionally stops and says, "I don't have reliable data right now" has imperfect uptime and builds trust over time. Most self-healing articles focus exclusively on uptime. That's the wrong metric for any data system that feeds decisions.

The hardest healing decision is "do nothing and wait." Every instinct in engineering says: fix it, retry it, work around it, keep the system running. But sometimes the right response to a data quality issue is to stop, surface the problem, and let a human decide. Building a self-healing system that knows when not to heal was harder than building the healing logic itself.

Invisible healing is dangerous healing. If a pipeline silently drops 23% of records and nobody knows, the healing makes things worse. It converted an obvious failure (pipeline stopped, dashboard shows no data) into a subtle failure (pipeline ran, dashboard shows wrong data). The subtle failure is more dangerous because people make decisions based on it. Every healing action should be visible to downstream consumers. If the pipeline healed itself, the data should say so.

AI agents make self-healing failures scale faster. When a human looks at a dashboard, they might notice that the numbers seem low and investigate. When an AI agent queries the table, it returns whatever is there with full confidence. Our NL-to-SQL interface told a product manager that engagement was "trending down" based on the incomplete Tuesday data. The agent had no mechanism to check the batch metadata, no way to know the pipeline had healed by dropping records, and no reason to doubt the result. Self-healing systems that don't communicate their healing status to AI consumers are creating governed-looking answers from ungoverned data.

What I'd Tell My Past Self

Build the healing. But build the communication first. A pipeline that fails loudly is better than a pipeline that heals silently. And the stakeholders who say they want data to always be available will change their minds the first time they make a decision based on data that was quietly incomplete.

Self-healing is not the goal. Self-awareness is the goal. A pipeline that knows what happened to the data, communicates it clearly, and lets downstream consumers (human and machine) decide what to do with that knowledge. That's the pipeline I'd build from the start.


Written by anushakovi | Data/Business Intelligence Engineer focused on building governed, trustworthy AI for data platforms and NL analytics.
Published by HackerNoon on 2026/04/02