How to Debug Model Loading Failures in ONNX Runtime: Complete Error Handling Guide
ONNX Runtime encapsulates every model loading failure in a common::Status object that exposes a category, specific error code, and human-readable message, allowing precise diagnosis of whether the failure stems from file system issues, protobuf corruption, or session configuration errors.
When InferenceSession::Load fails in ONNX Runtime, it returns a structured error object rather than throwing exceptions. Understanding how to extract and interpret this diagnostic data is essential for production debugging. This guide examines the Status class architecture in include/onnxruntime/core/common/status.h and demonstrates how to handle errors across the C++, C, and Python APIs when loading ONNX and ORT format models.
The Status Class Architecture
All error information in ONNX Runtime lives within the common::Status class defined in include/onnxruntime/core/common/status.h. A Status instance contains three critical diagnostic fields:
- Category – Either
SYSTEMfor OS-level failures orONNXRUNTIMEfor library-level errors. - Code – An entry from the
StatusCodeenum (lines 34-50) such asINVALID_ARGUMENT,NO_MODEL, orMODEL_LOAD_CANCELED. - Message – A free-form string generated at the failure point explaining the specific context.
The class provides IsOK() to check success and ToString() (lines 55-66) to render a human-readable diagnostic formatted as [Category::ONNXRUNTIME] FAIL: <msg>. Never ignore the return value of loading operations; always inspect this object before proceeding to Initialize().
Model Loading Entry Points
The public entry points for model loading are the overloads of InferenceSession::Load declared in onnxruntime/core/session/inference_session.h (lines 94-106). Internally, these delegate to one of three private helpers, each returning a common::Status:
LoadOnnxModel(const PathString&)– Parses an ONNX file from disk.LoadOrtModel(const PathString&)– Deserializes an ORT-format model.LoadOrtModel(const void*, int)– Loads a model from an in-memory buffer.
Each helper propagates errors from lower layers, such as protobuf parsing failures from core/graph/model.h or file system errors from Model::Load.
Common Model Loading Failure Codes
Mapping the reported StatusCode to its source file path accelerates debugging. The following codes frequently appear during InferenceSession::Load:
INVALID_ARGUMENT– Invalid session options or malformed file paths. Triggered by validation checks insideLoadbefore file operations begin.NO_SUCHFILE/NO_MODEL– The specified file does not exist or cannot be opened, originating inModel::Loadwithincore/graph/model.h.MODEL_LOAD_CANCELED– The user setSessionOptions::SetLoadCancellationFlag(true)before callingLoad. The session checkscheck_load_cancellation_fn_before proceeding.INVALID_PROTOBUF– The model file is corrupted or uses an incompatible protobuf version, raised duringLoadOnnxModelparsing.MODEL_REQUIRES_COMPILATION– The model requires ahead-of-time compilation (e.g., for TensorRT), detected inDoPostLoadProcessingafter graph construction.
Search for return ORT_MAKE_STATUS in onnxruntime/core/session/inference_session.cc to locate the exact origin of specific error codes.
Language-Specific Error Handling Patterns
C++ API: Inspecting the Status Object
In C++, capture the Status object returned by Load and probe its attributes before converting to a string:
#include "onnxruntime/core/session/inference_session.h"
#include "core/common/status.h"
onnxruntime::SessionOptions so;
so.session_log_severity_level = static_cast<int>(onnxruntime::logging::Severity::VERBOSE);
onnxruntime::Environment env(ORT_LOGGING_LEVEL_WARNING, "debug_env");
onnxruntime::InferenceSession session(so, env);
const std::wstring model_path = L"model.onnx";
onnxruntime::common::Status st = session.Load(model_path);
if (!st.IsOK()) {
LOGS_DEFAULT(ERROR) << "Failed to load model: " << st.ToString();
if (st.Code() == onnxruntime::common::StatusCode::MODEL_LOAD_CANCELED) {
LOGS_DEFAULT(ERROR) << "Load was cancelled – check SessionOptions::IsLoadCancellationFlagSet()";
}
return -1;
}
Alternatively, use ORT_THROW_IF_ERROR(st) to automatically throw an exception containing the Status message if the load fails.
C API: Extracting Messages from OrtStatus
The C API returns errors as an opaque OrtStatus* pointer. Always check for NULL and retrieve the message using OrtGetErrorMessage:
OrtEnv* env;
OrtCreateEnv(ORT_LOGGING_LEVEL_WARNING, "debug_c", &env);
OrtSessionOptions* opts;
OrtCreateSessionOptions(&opts);
OrtSetSessionLogSeverityLevel(opts, ORT_LOGGING_LEVEL_VERBOSE);
OrtSession* sess = NULL;
OrtStatus* status = OrtCreateSession(env, "model.onnx", opts, &sess);
if (status != NULL) {
const char* err = OrtGetErrorMessage(status);
fprintf(stderr, "ONNX Runtime load error: %s\n", err);
OrtReleaseStatus(status);
OrtReleaseSessionOptions(opts);
OrtReleaseEnv(env);
return -1;
}
Release the status object with OrtReleaseStatus to prevent memory leaks.
Python API: Catching RuntimeError
The Python bindings convert C API errors into Python RuntimeError exceptions. The exception message contains the exact output of Status::ToString():
import onnxruntime as ort
sess_options = ort.SessionOptions()
sess_options.log_severity_level = 0 # VERBOSE
try:
sess = ort.InferenceSession("model.onnx", sess_options)
except RuntimeError as e:
print("Model load failed:", e)
if "MODEL_LOAD_CANCELED" in str(e):
print("Load was cancelled – verify SessionOptions.set_load_cancellation_flag")
The conversion logic resides in python/onnxruntime_pybind_state.cc, which calls OrtGetErrorMessage under the hood.
Step-by-Step Debugging Workflow
Follow this systematic approach to diagnose model loading failures:
-
Enable verbose logging – Set
session_log_severity_leveltoORT_LOGGING_LEVEL_VERBOSEinSessionOptionsor exportORT_LOGGING_LEVEL=VERBOSEto capture the full execution trace. -
Capture the Status – Never ignore return values in C/C++. In Python, wrap the constructor in a try/except block.
-
Inspect the code – Map the reported
StatusCodeback to the source by searching for that constant inonnxruntime/core/session/inference_session.cc. -
Check cancellation flags – If you encounter
MODEL_LOAD_CANCELED, verify thatSessionOptions::SetLoadCancellationFlagwas not inadvertently set totruebefore loading. -
Validate the model file – Rule out protobuf corruption by running
onnx.checker.check_model(Python) or opening the file in Netron to verify node definitions and tensor shapes.
Summary
- ONNX Runtime reports all model loading failures through the
common::Statusclass defined ininclude/onnxruntime/core/common/status.h. - The
InferenceSession::Loadoverloads inonnxruntime/core/session/inference_session.hserve as the primary entry points, delegating toLoadOnnxModelorLoadOrtModelhelpers. - Key error codes include
INVALID_PROTOBUF,NO_MODEL,INVALID_ARGUMENT, andMODEL_LOAD_CANCELED. - Extract error details via
Status::ToString()in C++,OrtGetErrorMessagein C, andRuntimeErrorexceptions in Python. - Always enable verbose logging and validate model files independently to distinguish between runtime configuration issues and corrupted model data.
Frequently Asked Questions
What is the difference between SYSTEM and ONNXRUNTIME status categories?
The SYSTEM category indicates OS-level failures, such as file permission errors or out-of-memory conditions returned by the operating system. The ONNXRUNTIME category indicates library-level logic errors, such as invalid protobuf formats, unsupported ops, or configuration mistakes detected by ONNX Runtime's internal validation layers. Both categories use the same StatusCode enumeration but require different remediation strategies.
How do I detect if a load was cancelled versus failed due to file corruption?
Check the StatusCode enum value returned by st.Code() or scan the error message string for MODEL_LOAD_CANCELED. This specific code indicates that the load operation was interrupted because SessionOptions::SetLoadCancellationFlag(true) was called before or during the load. File corruption, by contrast, produces INVALID_PROTOBUF or NO_MODEL codes.
Why does Python raise RuntimeError instead of a specific exception class?
The Python bindings in onnxruntime_pybind_state.cc convert the underlying C OrtStatus* into a RuntimeError to maintain compatibility across versions and simplify the binding layer. The exception message preserves the full diagnostic detail from Status::ToString(), including the error code and human-readable description, allowing you to programmatically inspect the specific failure type by parsing the message string.
Where does the INVALID_PROTOBUF error originate in the codebase?
The INVALID_PROTOBUF code originates in onnxruntime/core/graph/model.h and model.cc during the call to Model::Load. When InferenceSession::LoadOnnxModel invokes the protobuf parser, any corruption, version mismatch, or truncation detected in the ONNX file triggers this status. You can validate the file independently using the onnx Python package or Netron before attempting runtime loading.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →