{"record":{"id":"c93deaca8f172e7c","repo":"NationalSecurityAgency/ghidra","slug":"data-table-is-corrupt-data-unit-and-its-datatype","errorCode":null,"errorMessage":"Data table is corrupt. Data unit and its datatype disagree on length.","messagePattern":"Data table is corrupt\\. Data unit and its datatype disagree on length\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"critical","filePath":"Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceData.java","lineNumber":102,"sourceCode":"\n\t@Override\n\tprotected void fresh(boolean created) throws IOException {\n\t\tsuper.fresh(created);\n\t\tif (created) {\n\t\t\treturn;\n\t\t}\n\t\tplatform = space.manager.platformManager.getPlatformByKey(platformKey);\n\t\tif (platform == null) {\n\t\t\tthrow new IOException(\"Data table is corrupt. Missing platform: \" + platformKey);\n\t\t}\n\t\tdataType = platform.getDataTypeManager().getDataType(dataTypeID);\n\t\tif (dataType == null) {\n\t\t\tthrow new IOException(\"Data table is corrupt. Missing datatype: \" + dataTypeID);\n\t\t}\n\t\tbaseDataType = getBaseDataType(dataType);\n\t\tfinal int dtLen = getDataTypeLength();\n\t\tif (dtLen != range.getLength() && dtLen != -1) {\n\t\t\tthrow new IOException(\n\t\t\t\t\"Data table is corrupt. Data unit and its datatype disagree on length.\");\n\t\t}\n\t\tdefaultSettings = dataType.getDefaultSettings();\n\t}\n\n\t@Override\n\tprotected void setRecordValue(DBTraceData value) {\n\t\t// Nothing. Entry is the value\n\t}\n\n\t@Override\n\tprotected DBTraceData getRecordValue() {\n\t\treturn this;\n\t}\n\n\t/**\n\t * Set the fields of this record\n\t * ","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Framework-TraceModeling/src/main/java/ghidra/trace/database/listing/DBTraceData.java#L84-L120","documentation":"Thrown by DBTraceData.fresh() when the data type's length (getDataTypeLength()) does not equal the stored range length, and the data type length is not -1 (variable-length). This means the persisted data unit's byte range and its data type's expected size disagree — a sign of internal inconsistency in the trace database. The unit cannot be safely interpreted because the type boundary and the recorded address range do not match.","triggerScenarios":"Loading a trace where a DBTraceData record's range.getLength() differs from the resolved DataType's length. For example, a 4-byte integer type stored over a 8-byte address range, or a struct that was resized after the unit was written.","commonSituations":"Data type definition changed size between writing and reading the trace (e.g., a struct had a field added); partial write due to crash; manual database tampering; version mismatch in built-in type definitions.","solutions":["Ensure the data type definitions (structs, enums, etc.) are identical between trace creation and trace loading — load the same archives.","Restore from a backup where the type definitions and trace data are consistent.","If intentional type changes were made, re-apply the data types to the affected addresses after opening, or recreate the trace data units."],"exampleFix":"// before — trace opens, struct size changed from 8 to 12\n// throws IOException: Data unit and its datatype disagree on length\n\n// after — load matching type archive before opening the trace\n// Ensure the struct definition in the loaded archive matches the\n// one used when the trace was created (same field layout / size).","handlingStrategy":"try-catch","validationCode":"// Cannot pre-validate individual records; ensure type consistency at archive level\n// Verify data type sizes match between the loaded archive and what the trace expects:\nDataType dt = dtm.getDataType(categoryPath, name);\nif (dt != null && expectedLength != dt.getLength()) {\n    Msg.warn(MyClass.class, \"Type size mismatch for \" + name);\n}","typeGuard":null,"tryCatchPattern":"try {\n    trace = dbTrace.openForReading(path);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"disagree on length\")) {\n        Msg.error(MyClass.class, \"Trace data/type length mismatch: \" + e.getMessage());\n        // Restore from backup or load matching type definitions\n    } else {\n        throw e;\n    }\n}","preventionTips":["Keep data type definitions consistent between trace creation and loading — do not modify struct layouts in between.","Load the exact same data type archive version that was used to create the trace.","Back up archives with traces as a consistent set."],"tags":["data-corruption","database","data-type","length-mismatch","trace-modeling"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}