Data Validation vs Data Verification: What Analysts Should Know
Data validation checks values against rules; data verification checks them against the source. See why you need both, with DuckDB SQL examples.
By Tnas · Published · 8 min read

Data validation checks whether values follow the rules they should follow: the right type, an allowed value, a plausible range. Data verification checks whether values match the real-world source they came from, such as the original document or the system of record. Validation can tell you a date is impossible; only verification can tell you a perfectly possible date is wrong. Analysts need both, and they catch different errors.
Key Takeaways
- Validation asks "could this value be right?" It compares data with rules and needs no outside source.
- Verification asks "is this value right?" It compares data with an authoritative source, such as a ledger, a source document or a second independent entry.
- A value can pass validation and still be wrong, and a value can fail an overly strict rule and still be correct. The worked example below shows both.
- Missing records are invisible to validation. Only a comparison with the source, such as a reconciliation of row counts and totals, finds rows that never arrived.
- In engineering standards the words mean something slightly different, so state which sense you mean when it matters.
What is the difference between data validation and data verification?
The difference is what each check compares the data with. Validation compares data with rules. Verification compares data with a source of truth.
| Data validation | Data verification | |
|---|---|---|
| Question | Could this value be right? | Is this value actually right? |
| Compared with | Written rules: types, formats, ranges, allowed lists, cross-field logic | An authoritative source: original documents, the system of record, an independent re-entry |
| Needs outside data? | No | Yes |
| Typical method | Automated rule checks on every row | Reconciliation, sampling against the source, double entry |
| Catches | Impossible, malformed and out-of-range values | Plausible but wrong values, missing and extra records |
| Misses | Wrong values that look plausible; records that never arrived | Errors already in the source; fields the source does not hold |
| Cost per row | Low, so it usually runs on everything | Higher, so it is often run on totals or samples |
A birth date of 1990-05-12 passes every reasonable validation rule. If the person was actually born on 1990-12-05 and the day and month were swapped at entry, only verification against the source document or another record will find it.
How do the standards define validation and verification?
Engineering standards use the two words in a slightly different way from everyday data work, which is a common source of confusion. NIST's glossary quotes the ISO 9000:2015 definitions:
- Verification: "Confirmation, through the provision of objective evidence, that specified requirements have been fulfilled" (NIST CSRC Glossary, "verification").
- Validation: "Confirmation, through the provision of objective evidence, that the requirements for a specific intended use or application have been fulfilled" (NIST CSRC Glossary, "validation").
In systems engineering, then, verification asks "did we meet the specification?" and validation asks "is it fit for its intended use?" Notice the twist: checking data against a written rule set is closer to the ISO sense of verification, yet data teams almost always call it "data validation".
This post uses the meanings common in data work, because those are what analysts meet in tools, job descriptions and pipeline code: validation is checking values against rules, verification is checking them against the source. When you write a data quality plan for a team that also follows engineering standards, define the terms at the top.
A worked example: one extract, two kinds of check
Here is a five-row invoice extract, loaded as text, and the finance ledger it was exported from. The ledger is the system of record:
CREATE TABLE invoices AS SELECT * FROM (VALUES
('INV-101', 'C-01', '2026-04-02', '1250.00', 'EUR'),
('INV-102', 'C-02', '2026-04-03', '980.00', 'GBP'),
('INV-103', 'C-03', '2026-04-05', '-40.00', 'EUR'),
('INV-104', 'C-01', '2026-04-31', '310.00', 'EUR'),
('INV-105', 'C-04', '2026-04-08', '7600.00', 'US$')
) AS t(invoice_id, customer_id, invoice_date, amount, currency);
CREATE TABLE ledger AS SELECT * FROM (VALUES
('INV-101', '2026-04-02', 1250.00, 'EUR'),
('INV-102', '2026-04-03', 890.00, 'GBP'),
('INV-103', '2026-04-05', -40.00, 'EUR'),
('INV-104', '2026-04-30', 310.00, 'EUR'),
('INV-105', '2026-04-08', 7600.00, 'USD'),
('INV-106', '2026-04-09', 455.00, 'EUR')
) AS t(invoice_id, invoice_date, amount, currency);
Both queries below were run in DuckDB 1.5.1; the column-type rows are removed from the output.
Validation: check every row against rules
Validation needs only the extract and four rules: the date must be a real date, the amount must be a number, the currency must be on the approved list, and the amount must be positive. The rules are checked in order, and each failing row gets the first reason it hits:
SELECT invoice_id,
CASE
WHEN TRY_CAST(invoice_date AS DATE) IS NULL THEN 'invalid date'
WHEN TRY_CAST(amount AS DECIMAL(12,2)) IS NULL THEN 'invalid amount'
WHEN currency NOT IN ('EUR', 'GBP', 'USD') THEN 'unknown currency'
WHEN TRY_CAST(amount AS DECIMAL(12,2)) <= 0 THEN 'amount not positive'
END AS validation_error
FROM invoices
WHERE validation_error IS NOT NULL
ORDER BY invoice_id;
┌────────────┬─────────────────────┐
│ invoice_id │ validation_error │
├────────────┼─────────────────────┤
│ INV-103 │ amount not positive │
│ INV-104 │ invalid date │
│ INV-105 │ unknown currency │
└────────────┴─────────────────────┘
Three rows fail. April has 30 days, so 2026-04-31 is impossible, and US$ is not on the approved currency list. The guide to validation rules and exception reports explains how to turn output like this into a report people can act on.
Verification: compare every row with the source
Verification joins the extract to the ledger and compares field by field. A full outer join keeps rows that exist on only one side. Like the validation query, the CASE reports only the first difference it finds in each row:
SELECT coalesce(i.invoice_id, l.invoice_id) AS invoice_id,
CASE
WHEN i.invoice_id IS NULL THEN 'missing from extract'
WHEN l.invoice_id IS NULL THEN 'not in ledger'
WHEN TRY_CAST(i.amount AS DECIMAL(12,2)) IS DISTINCT FROM l.amount
THEN 'amount differs: ' || i.amount || ' vs ' || l.amount
WHEN i.invoice_date IS DISTINCT FROM l.invoice_date
THEN 'date differs: ' || i.invoice_date || ' vs ' || l.invoice_date
WHEN i.currency IS DISTINCT FROM l.currency
THEN 'currency differs: ' || i.currency || ' vs ' || l.currency
END AS verification_issue
FROM invoices AS i
FULL OUTER JOIN ledger AS l USING (invoice_id)
WHERE verification_issue IS NOT NULL
ORDER BY invoice_id;
┌────────────┬────────────────────────────────────────┐
│ invoice_id │ verification_issue │
├────────────┼────────────────────────────────────────┤
│ INV-102 │ amount differs: 980.00 vs 890.00 │
│ INV-104 │ date differs: 2026-04-31 vs 2026-04-30 │
│ INV-105 │ currency differs: US$ vs USD │
│ INV-106 │ missing from extract │
└────────────┴────────────────────────────────────────┘
What each check caught
Putting the two results side by side shows why neither is enough alone:
| Invoice | Validation | Verification | What was really going on |
|---|---|---|---|
| INV-101 | Pass | Pass | Correct |
| INV-102 | Pass | Amount differs | Digits transposed (890 keyed as 980). Plausible, so no rule can catch it |
| INV-103 | Fails "positive amount" | Pass | A legitimate credit note. The rule was too strict, not the data wrong |
| INV-104 | Invalid date | Date differs | Wrong in a way both checks can see |
| INV-105 | Unknown currency | Currency differs | A formatting variant the ledger stores as USD |
| INV-106 | Not checked | Missing from extract | A whole record lost in export, invisible to any row-level rule |
INV-102 and INV-106 are the important rows. A transposed amount and a missing record are both errors that change totals, and validation cannot see either of them. INV-103 shows the opposite risk: a validation rule written without input from finance would have quarantined a correct row. The lesson on ranges and the order of rules covers how to set ranges that allow real exceptions such as refunds.
When should analysts use each?
Use validation on every row, every time data arrives (the data quality checks every pipeline should run are mostly validation rules). It is cheap, it needs nothing but the data and the rules, and it catches the errors that break code and reports: malformed dates, text in number columns, unknown categories. It belongs at the start of every cleaning pipeline, and the common data quality problems it targets each have a short detection query.
Use verification wherever an authoritative source exists and the cost of a wrong number is high. Three practical forms:
- Reconciliation of totals. Compare row counts and sums per period or per file with the source system. This is the cheapest form of verification and the one that finds missing records. The guide to reconciliation shows how to prove nothing was lost.
- Record-level comparison. Join to the source and compare fields, as in the example above, when both datasets are available to you.
- Sampling against source documents. When the source is paper forms or PDFs, check a sample of records by hand and record the error rate you find.
Full verification of every value is often too expensive, and regulators have encouraged a move away from it. The US Food and Drug Administration's guidance on monitoring clinical trials notes a growing consensus that risk-based approaches, focused on the most critical data, are more likely than routine visits to every site and 100% data verification to ensure study quality (FDA, "Oversight of Clinical Investigations — A Risk-Based Approach to Monitoring", 2013). The same logic works for analysts: verify the fields that drive decisions, such as amounts and dates, and validate everything.
Frequently asked questions
Is data validation part of data cleaning?
Yes. Validation is one of the core steps of data cleaning: after values are parsed and standardized, rules decide which rows are clean and which go to an exceptions table with a reason. Verification usually happens alongside cleaning, often as a reconciliation step at the end.
Can data be valid but inaccurate?
Yes. A valid value only satisfies the rules; it can still be the wrong value. Transposed digits, a swapped day and month that still form a real date, and an address that exists but belongs to someone else are all valid and inaccurate. Only verification against a source catches them.
What is double data entry?
Double data entry is a verification method for manually keyed data. Two people, or one person twice, enter the same source documents independently, and a program compares the two versions. Any disagreement is checked against the original document. It verifies the keying step, but it cannot catch an error that is already in the source.
Is a schema check validation or verification?
In everyday data work, a schema check is validation: it confirms that columns, types and required fields match a declared schema, without consulting any outside source. In ISO terminology it would count as verification against a specification, which is another reason to define your terms. How to validate a CSV's schema before it reaches your warehouse covers schema checks in detail.
Practice both kinds of check
Validation and verification are both skills you get faster at with practice. Try validating invoice totals and errors versus warnings for rule-based checks, then validate against the referenced record and totals that reconcile with missing keys for checks that compare one dataset with another.
Related reading
Sources
- NIST Computer Security Resource Center. Glossary entries validation and verification, citing ISO 9000:2015. Retrieved 2026-11-05.
- US Food and Drug Administration (2013). Guidance for Industry: Oversight of Clinical Investigations — A Risk-Based Approach to Monitoring.