DIR eCPR XML upload errors: why uploads bounce and how to fix them
The state's schema is strict in ways the portal does not always explain. Here are the rules it enforces, the mistakes that trip each one, and what to do when the upload validates and then nothing appears.
What a bounce looks like
Two things happen to bad XML. Sometimes the portal names a pattern it could not validate. More often the file appears to upload and then the form stays blank. DIR's own FAQ describes exactly that case, an upload the site accepts that shows nothing when you click to load it, and gives the diagnosis in one line: there is most likely an error in your code, review the submission, resend the corrected file, and if the problem persists email the eCPR inbox at publicworks@dir.ca.gov (DIR eCPR FAQ, problems uploading).
Where the rules live
DIR publishes three things on its certified payroll reporting page: the CPR XML schema (version 1.3), the CPR XML guidelines, and a sample XML file. The guidelines document itself is dated January 2016, Version 1.10, on its own cover page (eCPR XML Guidelines), and nothing in the document shows a later revision. Every rule below comes from those documents or from live validation behavior against them.
The rules that bounce uploads
- Employee name id format. Each employee record carries an id of the form social security number, two colons, then the worker's name exactly as written elsewhere in the record, all upper case, not reordered. The schema's own documentation for the name element gives the example, for worker John Smith, of
id="123456789::JOHN SMITH", first name first (CPR XML schema). Name formatting is one issue a payroll vendor identified after the portal relaunch, flagged in April 2025 alongside other, unrelated upload problems the vendor logged over the prior year (one vendor's transition note). - Social security number. Exactly nine digits, no dashes, per the schema's ssn element (CPR XML schema). The eCPR carries the full number, unlike the federal WH-347, whose instructions call for only the last four digits of the worker's SSN, or another worker-specific identifying number, and say the full SSN must not be included (WH-347 instructions).
- Withholding exemptions. One or two digits. Not blank, not a decimal (CPR XML schema). A live server error names the pattern when this is wrong.
- Dates. Four digit year, two digit month, two digit day, everywhere: the week ending date and every day worked (CPR XML schema).
- Days. Exactly seven day elements, numbered 1 through 7, each with its own date inside the week ending on the week ending date. The live schema requires all seven in every submission; enter zero hours for a day not worked rather than leaving it out (CPR XML schema).
- Project block. Both the DIR project ID and the contract agency (the entity you contracted with) are mandatory, per DIR's eCPR XML guidelines. The rest of the block's fields are present in the sample but empty; see the table below for the exact element names.
- Payroll number and amendment number. Leave them empty. DIR assigns both (eCPR XML guidelines).
- Statement of non performance. If the week is a no work week, the flag is true and there are no employee records at all (CPR XML schema).
- Deductions, contributions, and payments. The schema groups fourteen categories under one block: federal tax, FICA, state tax, SDI, vacation and holiday, health and welfare, pension, training, fund administration, dues, travel and subsistence, savings, other, and a total. Each one is a plain decimal amount; the schema's own note says only to check with accounting on what belongs in each category (CPR XML schema).
- Notes. Up to 256 characters, per the schema (CPR XML schema).
- License type and registration. The license type comes from the allowed set. The public works registration number is required; the only alternative is a literal NA (CPR XML schema), which is a bigger problem than a bounced file (registration explained).
- Contractor name length. One to fifty six characters, per the schema's contractorName element (CPR XML schema).
- Amendments replace by resubmission. DIR's FAQ says that to correct a submitted payroll, you resubmit an eCPR for that workweek, and the amended eCPR replaces the original payroll submission (DIR eCPR FAQ). DIR's FAQ does not publish a list of fields the resubmission must match to the original.
- File name. The last four of the FEIN, the project ID, and the week ending date, separated by underscores, ending in .xml (eCPR XML guidelines, section 5).
- Declaration and namespace. A UTF-8 XML declaration at the top and the DIR namespace declared on the root element (CPR XML schema).
- Numbers that should reconcile. The schema defines total hours, gross for this project, gross for all work, net wages, and the deductions total as independent decimal fields; it does not document any of them as calculated from the others (CPR XML schema). Even so, keep them consistent: daily hours should sum to the totals, gross for this project should not exceed gross for all work, net wages should fall between zero and gross for all work, and the deductions total should match the sum of the deductions entered above it. A payroll where those numbers do not line up will draw scrutiny even though the schema itself does not check for it.
- Element order and empty elements. The schema is a sequence, so elements must appear in the documented order, and placeholder elements that carry no value must still be present, empty (CPR XML schema).
The project block, field by field
The project block is a fixed sequence named CPR:ProjectInfo. Every element below must appear, in order, even when empty, per DIR's eCPR XML guidelines and its sample file.
| Element | What it holds |
|---|---|
awardingBody | Present, empty in the sample. |
contractAgencyID | A placeholder DIR added to separate multiple contractors on one project. Leave it empty. |
contractAgency | The entity you contracted with, for example the general contractor or the awarding body. Mandatory. |
projectName | Present, empty in the sample. |
projectID | The DIR project ID, also called the PWC-100 number. Mandatory, along with contract agency above. If you do not have it, the schema says entering awardingBodyID, projectNum, and contractID instead lets DIR look up the project (CPR XML schema). |
awardingBodyID | Present, empty in the sample. |
projectNum | Present, empty in the sample. |
contractID | Present, empty in the sample. |
projectLocation | Nested block: description, street, city, county, state, zip. Present, empty. |
Filling in a field DIR leaves empty in its own sample does not break the schema, but it adds a value the state's template does not carry. A field like that is a vendor choice, not a DIR requirement.
What to do when it bounces
- Open the guidelines and the sample file from the DIR page above and compare your file's structure to the sample, element by element, in order.
- Validate locally against the published schema before you upload again. A file that fails the schema on your machine will never load in the portal.
- Check the five usual suspects first: the name id, the SSN format, the dates, the day numbering, and any populated payroll or amendment number.
- If it validates locally and still fails, resend and email publicworks@dir.ca.gov with the exact error text, as the FAQ directs. Keep the email and the confirmation with your records.
When it is the state's system, not your file
Not every bounce is a bad file. A portal that will not load, times out, or throws a generic server error instead of naming a pattern points at the state's system, not your XML. DIR's own FAQ describes one version of this: a file the site accepts as valid, that then shows nothing when you click to load it. The fix is the same either way: resend, and if it persists, email publicworks@dir.ca.gov.
DIR has acknowledged in writing that its eCPR system does not always work as intended. In a notice on its public works notices page, the department said it "does not want contractors to be penalized just because they are having some difficulty using DIR's eCPR system." That notice dates to the system's original rollout, not to a current outage, and it is not a guarantee against the late filing penalty under Labor Code 1771.4(a)(3)(B) and (C), $100 a day up to $5,000 per project, levied once the records are 14 days past due. Treat it as a reason to document a real outage: screenshot the error and keep your email to DIR as the record.
The upload that never bounces
Our engine builds the eCPR from your payroll export and checks it against the published schema and the arithmetic identities before anything is written. A person reviews every filing against the project and the wage determination. You review and sign, because the declaration under penalty of perjury is yours (Labor Code 1776). No XML on your desk, ever. For the full workflow around that signature step, see how to submit certified payroll to DIR.