Skip to main content
L
Loopaloo
Buy Us a Coffee
All ToolsImage ProcessingAudio ProcessingVideo ProcessingDocument & TextPDF ToolsCSV & Data AnalysisConverters & EncodersWeb ToolsMath & ScienceGames
Guides & BlogAboutContact
Buy Us a Coffee
L
Loopaloo

Free online tools for developers, designers, and content creators. Your files are processed in your browser and are never uploaded - no accounts required. A few network utilities (like What's My IP and Currency Converter) call public APIs to do their job and say so on their pages.

support@loopaloo.com

Tool Categories

  • Image Tools
  • Audio Tools
  • Video Tools
  • Document & Text
  • PDF Tools
  • CSV & Data
  • Converters
  • Web Tools
  • Math & Science
  • Games

Company

  • About Us
  • Contact
  • Blog
  • FAQ

Legal

  • Privacy Policy
  • Terms of Service
  • Disclaimer

Support

Buy Us a Coffee

© 2026 Loopaloo. All rights reserved. Built with privacy in mind.

Privacy|Terms|Disclaimer
  1. Home
  2. CSV & Data Analysis
  3. CSV Data Validator
Add to favorites

CSV Data Validator

Validate columns against rules that name their definition: the email rule browsers enforce, a URL scheme allowlist, calendar-checked dates, and every failure explained

Rows never leave your deviceMore csv & data analysisJump to full guide

Initializing in your browser…

You might also like

CSV Data Type Detector

Classify every column against a decider rather than a regex: calendar-checked dates, RFC 4291 addresses, and leading zeros kept out of integer columns

CSV Missing Data Analyzer

Count what is missing in five categories that add up to the grid, with the tokens that mean missing your choice

CSV Formatter & Validator

Format and validate against RFC 4180 by section, with output verified by reading it back

A sample run

Before an import you need every email well formed, every age at least 18, and every link a real web address.

Rules

email: Email  ·  age: Min value 18  ·  site: URL
What CSV Data Validator produces

Report

6 errors in 3 of 4 rows
row 3 email  the domain has an empty label between two dots
row 3 age    17 is below the minimum of 18
row 3 site   the scheme is javascript:, and this rule allows http: and https:
row 4 site   no scheme; a bare host is not a URL  ->  try https://example.com
row 5 age    "12abc" is not a number, so it cannot be compared to a bound

Each failure names the rule and the reason. `bob@example..com` fails because the WHATWG production browsers enforce requires every domain label to start and end with an alphanumeric, which the usual email pattern does not check. `javascript:alert(1)` fails because a URL rule allows http and https by default, and that is what stops a script being stored in a link column. And `12abc` fails a numeric bound rather than passing it as 12, which is what parseFloat would have made it.

Validation Rules That Say What They Accept

Check every cell in a column against a rule and get told exactly which values fail and why. The difference from most validators is what each rule actually enforces: the email rule is the one browsers enforce, the URL rule has a scheme allowlist so it refuses javascript:, the date rule goes through the calendar so it refuses 29 February 2025, and the phone rule counts digits rather than characters.

How to use

  1. 1Upload your CSV file, or load the sample
  2. 2Add a rule per column, or start from a template
  3. 3Set the rule options where it matters: the allowed URL schemes, whether a pattern matches the whole value, whether empty cells are skipped
  4. 4Click Validate and read the errors, each with the reason and a suggested fix
  5. 5Download the report, or download the file with the failing rows removed

Key features

  • 18 rule types: required, not blank, regex, min and max length, min and max value, email, URL, numeric, integer, date, time, date and time, phone, unique, in list, and UUID
  • Email checked against the WHATWG HTML production that browsers enforce, which catches malformed domain labels and accepts a dotless domain
  • URL checked against the WHATWG URL parser plus a scheme allowlist, so javascript: and data: are refused by default and can be widened per rule
  • Dates checked against the calendar, so 2025-02-29 and 2025-04-31 fail and a bare number is not silently a date
  • Times checked against the clock, including 24:00 and a 23:59:60 leap second
  • Phone numbers checked by digit count against the E.164 limit, not by character count
  • Numeric bounds that refuse anything not entirely a number, so 12abc does not pass a minimum of 10
  • Regex patterns anchored to the whole value by default, with a switch for substring matching and one for case
  • Lengths counted in Unicode code points, so an emoji is one character
  • Every rule can skip empty cells, so a column of optional values is not reported as entirely wrong
  • A uniqueness check that indexes the column once, so 10,000 rows take about 25 milliseconds
  • Every error names the rule and the reason, with a suggested fix where one exists
  • A summary of exactly what was checked, shown alongside the results
  • Live validation over the first 50 rows while you build the rules
  • Download a report, or the file with the failing rows removed

How it works

A validator that rejects something valid is annoying. A validator that ACCEPTS something invalid is the entire failure mode, because the file then passes and the bad row is discovered by whatever consumes it. Measured on 2026-09-01 against a 126-case corpus, with every corpus answer cross-checked against an independent decider first, the previous version of this tool was right on 94 cases and accepted 24 values that should have been rejected.

The email pattern was the usual one, which says nothing about the shape of a domain label. It accepted someone@example..com (an empty label between two dots), someone@.example.com, someone@example.com., someone@-example.com and someone@example-.com. It also rejected someone@localhost, which is a valid address: the WHATWG HTML production every HTML5 form enforces deliberately allows a domain with no dot. The rule here is that production, which gets all seven right because it requires every label to start and end with an alphanumeric.

The URL rule was `new URL()` alone, and the WHATWG URL parser is not a URL validator: it parses javascript:alert(1), data:text/html with markup in it, file:///etc/passwd and foo:bar quite happily. A column of web addresses that accepts a javascript: value is storing something that will later be rendered as a link. The rule here is the parser plus a scheme allowlist, http and https by default, which you can widen per rule; the failure names the scheme it saw and says why it matters, and a bare host like example.com is refused with the https:// form suggested.

The date rule was `new Date()`, which is not a date validator either. It accepted 2025-02-29 (2025 is not a leap year) and 2025-04-31 (April has 30 days), and, worse, the bare strings 2025, 5 and 0, because new Date("5") is 1 May 2001. The rule here goes through the calendar, and a bare number is refused with a message saying it is a number rather than a date.

The phone rule counted characters between 7 and 20 from a set that included dashes, spaces, plus signs and brackets, so seven dashes, seven brackets and seven plus signs were all valid telephone numbers, and so was 2025-03-04. The rule here counts DIGITS, requires between 7 and 15 of them because E.164 caps an international number at 15, refuses anything shaped like a date or a time, and allows at most one balanced bracketed group.

The numeric bounds used parseFloat, and parseFloat("12abc") is 12, so 12abc passed a "minimum 10" rule. A bound is only meaningful on something that is entirely a number, so it now refuses anything that is not and says which characters were the problem. And the regex rule was an unanchored test, which is a substring match: a pattern of five digits passed abc12345xyz. Patterns are now anchored to the whole value by default, with a switch for the substring behaviour, so whichever you get is visible rather than a surprise.

Every failure carries a reason naming the rule and, where there is one, a concrete next step: the nearest entry in an allowed list, the https:// form of a bare host, how many characters to remove. And because the results replace the rules panel, the results now carry a summary of what was checked, so the definition each rule enforces is still on screen at the moment an error makes you want it.

Where this fits a data pipeline

  • Pre-import validation

    Find the rows a database or an API will reject before you send them, with the reason for each, rather than after a partial load.

  • Cleaning a contact list

    Catch the malformed addresses a common email pattern lets through, such as a domain with an empty label or one starting with a dash.

  • Checking a column of links

    Refuse javascript: and data: values in a URL column, which are exactly what a permissive check lets through and what later gets rendered as a link.

  • Enforcing a controlled vocabulary

    Use an in-list rule to require one of a fixed set of values, and get the nearest allowed entry suggested for each near miss.

Frequently asked questions

Why is someone@localhost valid?

Because it is, under the definition browsers enforce. The WHATWG HTML valid e-mail address production allows a domain with no dot so that intranet hosts work, and a real <input type="email"> accepts it. The same definition is what refuses someone@example..com and someone@-example.com, which the usual pattern accepts.

Why is my ftp:// address failing the URL rule?

The URL rule allows http and https by default, because that is what a column of web addresses normally holds, and because the same allowlist is what refuses javascript: and data:. Each URL rule has its own list of allowed schemes, so add ftp to it and the value passes.

Does my regex have to match the whole value?

By default, yes, and the failure message says so. An unanchored test is a substring match, which means a pattern of five digits would pass abc12345xyz, and almost nobody means that. Turn off "Match the whole value" on the rule if you do.

What happens to empty cells?

By default an empty cell fails whatever rule is on the column, which is what you want when the column is mandatory. Turn on "Skip empty cells" for an optional column, and add a separate Required rule where presence itself is the thing you are checking.

Why did 12abc fail a minimum of 10?

Because it is not a number. parseFloat reads it as 12, which is how it used to pass, but a numeric bound only means something on a value that is entirely a number. The error says which characters made it fail.

What is the difference between Required and Not blank?

Required accepts any cell that is not empty, including one holding only a space. Not blank requires at least one character that is not whitespace.

How large a file can it check?

Everything runs in your browser and the uniqueness check indexes each column once rather than rescanning it per cell, so 10,000 rows with a uniqueness rule complete in about 25 milliseconds.

Private by design

Rows and columns are parsed and transformed in memory in your browser. No record ever reaches a server.