How to read CSLB's workers'-comp data without drawing the wrong conclusion

The CSLB files contain traps that produce confidently wrong numbers — cancelled policies, an incomplete inline column, exemption codes and garbage dates. Here is each one and how to handle it.

The two most common mistakes are counting cancelled policies as live, and reading the Master List's inline workers'-comp column as complete. The inline WCExpirationDate is populated on only about half of licences; the separate WorkerCompData file is authoritative — but it also contains cancelled policies that must be excluded, and both files contain dates outside any plausible range.

If you work with the CSLB files directly — or you are evaluating a vendor who claims to — these are the specific things that go wrong. Every one of them produces a number that looks reasonable and is not.

Which file is authoritative for policy expiry?

WorkerCompData, not the Master List. The Master List carries inline workers'-comp columns (WCInsuranceCompany, WCExpirationDate, and so on) but on the 12 August 2026 pull only 122,064 of 243,555 rows had an inline expiry — about 50%. Reading only that column loses half the population silently.

The catch is that the reverse is also true in a smaller way: 1,670 active licences carry an inline expiry while the WorkerCompData file has no live row for them. So the correct rule is prefer the dedicated file and fall back to the inline column, rather than using either alone. Where both exist they agree 99.06% of the time.

Do you have to exclude cancelled policies?

Yes, and this is the mistake with the largest effect. WorkerCompData contains historical rows, including policies with a CancellationDate. A cancelled policy still has an expiration date sitting in the file, and if you count it you will report expirations that cannot happen.

On the 12 August file: 249,225 raw rows reduce to 203,456 once cancelled rows are dropped and each licence is deduplicated to its latest live expiry. Skipping that step inflates every window count.

What does "Exempt" mean in the coverage-type field?

It means the licensee has certified they have no employees and therefore claims no workers'-comp obligation. It is not an error and it is not missing data — 113,333 of 232,052 active licences (48.8%) legitimately carry it.

Where it becomes a trap is if you treat exempt licences as prospects for a lapse campaign. They have no policy to lapse. The coverage-type values on the current file:

Coverage typeActive licences
Workers' Compensation Insurance113,765
Exempt113,333
Leasing firm / temp agency3,185
Licence does not have current W/C1,174
Out of state393
Self-insured202

Note that fourth row — "licence does not have current W/C" — 1,174 active licences openly flagged as uncovered.

Are the dates trustworthy?

Mostly, with one caveat you must handle. Every date column parses cleanly as MM/DD/YYYY once values are stripped of whitespace, but the file contains out-of-range values: 24,313 IssueDate values fall outside 1990–2100, including years like 2207. Bound your date parsing and null anything implausible rather than letting it skew a sort.

And strip before you parse. Values arrive with leading spaces, and an unstripped %m/%d/%Y parse silently yields zero valid dates rather than an error — a failure mode that looks like an empty dataset instead of a bug.

What about licences that look active but are in trouble?

Two status fields, and most analyses read only the first.

  • PrimaryStatusCLEAR for active, plus suspension values: Contr Bond Susp (6,182), Work Comp Susp (3,333), Liab Ins Susp (599) and a long tail of judgment, citation and family-support suspensions.
  • SecondaryStatus — populated on 6,352 licences and easy to miss entirely. 3,374 of those are WC Susp Pending on licences whose primary status is still CLEAR: a workers'-comp suspension in motion against a contractor who is still operating normally.

If you only read PrimaryStatus, that second group is invisible to you.

How are classifications formatted?

Inconsistently, which breaks naive filtering. The Classifications(s) column is pipe-separated and mixes formats — C57 and C-6 styles both appear, sometimes with spaces: A| B| C10| C36. Normalise by stripping, upper-casing, inserting the hyphen and splitting on the pipe, or a filter for C-10 will miss every row written as C10. One licence in the current file carries 21 classifications.

Is county usable as a filter?

Yes, with one gotcha: county names are title-cased (Los Angeles), and 95.0% of active licences have one. An exact-match filter for LOS ANGELES returns nothing at all. Normalise case on input.

How current is the file?

Continuously updated, not weekly-batched. Per-record LastUpdate timestamps show thousands of records changing within any given week, and the portal page states the "as of" date for the export. That is why a lapse list should be rebuilt from a fresh pull rather than cached — and why a digest built on a stale snapshot should be withheld rather than sent.

Where do you download it?

The CSLB data portal publishes the Master List, WorkerCompData and Personnel files. There is no static download URL: the portal renders the download links only after a form postback, so scripted access has to drive that flow rather than fetching a fixed address.


Sources: CSLB Master List (243,555 rows) and WorkerCompData (249,225 rows) files dated 12 August 2026; CSLB Public Sales Record Layout (Rev. 11/2020) for field semantics. All counts computed directly from those files.

See this in your own county

LapseWatch sends the California contractors in your territory whose workers'-comp policy or licence is about to expire — with phone, address and current carrier.

← All posts