I Built an Autodesk CER Viewer to Read Civil 3D Crash Reports

Autodesk moved CER crash reports from XML to binary protobuf with the 2025 products. Here is the viewer I built to read both, the parser bug that made me misreport the data twice, and the real numbers on the drawing field.

Civil 3D crashed. Autodesk wrote a crash report to disk. I opened the folder and found a binary file I could not read.

I had been reading those reports for years when they were xml. On my side of the fence the question is never “what is the faulting module,” it is “which drawing, on which machine, on which project.” So losing the ability to open the file mattered more than it sounds.

What changed underneath us

A CER folder, Customer Error Report, is what Autodesk drops on disk when the product falls over.

Through the 2024 products, every one of those folders held a dmpuserinfo.xml. Double-click and the browser renders it through an XSL transform. Ugly, and it buries the five fields I care about under a wall of DirectX diagnostics, but readable in about ten seconds.

Starting with the 2025 products the report arrives as .pb files instead. Protobuf, so binary, and double-clicking one gets you nothing. The only thing on the machine that can read it is cer_rawdataviewer.exe, which Autodesk installs alongside the CER service and never mentions to anyone.

My assumption is that this was a wire-size decision. If you are ingesting crash telemetry from millions of seats, XML is an expensive way to move bytes, and protobuf is the obvious answer. I have no visibility into why they actually did it.

Either way the cost landed on my end. Autodesk sees a module name. They do not see your reference tree, your template, or the dataset somebody built wrong in 2019, and those are the crashes I can actually fix.

First version: Python, tkinter, PyInstaller

I already had a parser. My CER analysis pipeline had been chewing through XML reports for a while, so the reading logic existed. What did not exist was a window.

So the first build was Python with tkinter, wrapped by PyInstaller into a single windowed exe. Header strip across the top with product, version, user, machine, crash time and exception. Tabs underneath. Open a crash folder, get an answer. That build took an afternoon because the parser was already written. The rough edges took considerably longer, and I will get to the one that cost the most.

Two decisions from it still hold.

I did not write a protobuf decoder. The schema is Autodesk’s, it is undocumented, and it can move under me. Shelling out to their own cer_rawdataviewer.exe means I am not maintaining a decoder for a format I cannot see the spec for. That is the actual benefit, and it is narrower than “compatibility for free”: if they change what the keys mean my field mapping still breaks, I just do not have to re-implement the parsing to find out.

I also kept one parser feeding two front ends. The viewer carries a vendored copy of the pipeline’s parser plus a hash lock, and the build warns me when the copy has drifted from the source. Fix upstream, sync, rebuild.
https://btl-blog.com/cer-xml-format-reference/
https://btl-blog.com/cer-pb-v7-format-reference/

The mistake that cost the most:
The parser pulled a list of known keys into normalized columns and quietly dropped everything else the decoder emitted.

So when a field looked missing I would go looking for it across the archive, not find it, and conclude the new format no longer carried it. I got that wrong twice on the same field, a year apart. The decoder was always emitting everything. My own code was throwing it away before I ever saw it.

The fix shaped the rewrite: keep the normalized set for reporting, and keep every original value alongside it. On a typical XML crash that is around 500 raw paths against the 60 that survive normalization. When two crashes look identical, the answer is almost always sitting in a field nobody thought to map.

Version two, in C#The Python build still works and is still in the repo. But tkinter has a ceiling and this had stopped being a weekend script.

The current one is C# WinForms, self-contained win-x64, single exe, no install. Tabs for Summary, Analysis, Similar, AI Prompt, System, Graphics, Session, Raw, and then two that exist because of the mistake above: XML (original) and PB (decoded), showing every value the file actually contained rather than every value I mapped.

One 2026 crash with no XML at all, 199 fields decoded from 3 .pb files. ACCESS_VIOLATION in dswhip.dll, last command REGEN, and the working document present.
Same crash, normalized fields with the raw decoded keys underneath and a filter across both.

One clarification, since I have described this as “one parser” before and that is no longer accurate. The C# build re-implements the rules rather than sharing the Python code. What keeps them honest is parity_check.py: it runs the Python parser and the C# exe over the same fixtures and diffs them field for field, exit 0 only on a full match, with two derived flags deliberately excluded. That is a test harness, not a shared engine, and it catches drift rather than preventing it.

Point it at a whole collection and you get a lazy tree down the left. Users expand to crashes, a crash is parsed only when you click it, so a large collection opens instantly. Markdown export for one crash, batch export for a whole tree. File associations are opt in, current user only, no admin.

I even have a tab with a custom generated prompt containing values from the CER to further research using AI.

What I found when I ran it across the archive

Building the viewer was supposed to be a convenience project. Then I pointed it at everything.

The measurement below is the whole archive, not a sample, covering crashes from March 2023 to September 2026. “Reports the drawing” means the parsed working-document field is non-empty, from the XML WorkingDocument element or, on the binary side, RP/Dwg. I re-ran it after fixing the allowlist bug, using the full decoded key set, because the numbers I published before that fix were measured through the filter that was losing data.

PopulationReports the drawing
XMLabout 88%
Both formats presentabout 88%
Binary only, all appsabout 6%
Binary only, Civil 3Dabout 45%

Binary-only crashes are dominated by background processes: Autodesk Genuine Service, ADP-SDK, Desktop Connector, the install service. None of those ever have a drawing open, so counting them against an XML population that is almost entirely Civil 3D compares two different things.

Restrict both sides to Civil 3D and the honest version is a drop from roughly 88% to roughly 45%. Real, worth knowing about, and half the size of what I first reported. The Civil 3D binary-only group is still small, a few dozen crashes across the 2025, 2026 and 2027 builds, so treat that 45% as a direction, not a rate I would defend.

The tool reads the field wherever it appears. It probes RP/Dwg first, then three other keys that have never once fired in this archive, and falls back to the XML element when XML is present. Nothing is being dropped now. The field is simply absent from most binary-only reports.

https://btl-blog.com/cer-xml-format-reference/
https://btl-blog.com/cer-pb-v7-format-reference/

Should I release it?

I get asked this every time I show it, so I am thinking about it seriously.

The case for: I have not found another viewer that reads both formats, and the binary one is only going to get more common as firms move to 2025 and up.

The case against: it depends on an Autodesk-installed decoder I do not control, the .pb schema is undocumented and can move under me, and support for a free tool is still support.

If you would use it, say so. That is genuinely the deciding factor. Leave a comment or find me on LinkedIn, and if there is real interest I will put a build and the docs somewhere public.

Cheers,
Shaan.

Update: I released it
https://btl-blog.com/2026/09/25/announcing-my-free-autodesk-cer-viewer-for-windows/

Shaan Hurley
Shaan Hurley
Articles: 4668

2 Comments

    • Thank you for attending the class! I will package the CER viewer executable up for distribution. I just have one more UI pass to make. After I get it dialed in I can also release the code at some point. It is just nice being able to open CER files no matter the format.

Leave a Reply

Discover more from Between the Lines Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading