rust-embedded/rust-raspberrypi-OS-tutorials · critical
Error during driver post-init callback: {}: {}
Error message
Error during driver post-init callback: {}: {} What it means
A driver registered a post-init callback with its descriptor; after the driver's init() succeeds, init_drivers_and_irqs invokes that callback, and it returned Err. The manager panics, naming the driver via its compatible string and the callback's error message. Post-init callbacks encode cross-driver or system-level setup, so their failure aborts bring-up.
Source
Thrown at 20_timer_callbacks/kernel/src/driver.rs:142
/// # Safety
///
/// - During init, drivers might do stuff with system-wide impact.
pub unsafe fn init_drivers_and_irqs(&self) {
self.descriptors.read(|descriptors| {
for descriptor in descriptors {
// 1. Initialize driver.
if let Err(x) = descriptor.device_driver.init() {
panic!(
"Error initializing driver: {}: {}",
descriptor.device_driver.compatible(),
x
);
}
// 2. Call corresponding post init callback.
if let Some(callback) = &descriptor.post_init_callback {
if let Err(x) = callback() {
panic!(
"Error during driver post-init callback: {}: {}",
descriptor.device_driver.compatible(),
x
);
}
}
}
// 3. After all post-init callbacks were done, the interrupt controller should be
// registered and functional. So let drivers register with it now.
for descriptor in descriptors {
if let Some(irq_number) = &descriptor.irq_number {
if let Err(x) = descriptor
.device_driver
.register_and_enable_irq_handler(irq_number)
{
panic!(
"Error during driver interrupt handler registration: {}: {}",View on GitHub (pinned to 644474cc09)
Solutions
- Read the compatible name and error payload in the panic message to locate the failing callback.
- Fix the callback so its operation succeeds, or move its work into the driver's init() if that is the right phase.
- Ensure dependent subsystems (e.g. IRQ manager) are registered before init_drivers_and_irqs runs.
- If the callback is optional for the current board, drop it from the descriptor.
Example fix
// before
let desc = DeviceDriverDescriptor::new(driver, Some(post_init))
.with_irq_number(irq); // post_init calls irq_manager before it exists
// after
// register the IRQ manager first, or remove the eager IRQ setup from post_init
fn post_init() -> Result<(), &'static str> {
// safe: dependencies are up by the time this runs
setup_timer_interrupt()
} Defensive patterns
Strategy: validation
Validate before calling
// before registering a descriptor, ensure callback dependencies exist:
if post_init_needs_irq_manager() && !irq_manager_registered() {
return Err("post_init requires an IRQ manager that is not yet registered");
} Try / catch
// replace panic in callback dispatch with logged failure:
if let Err(x) = callback() {
log_warn("post-init callback failed for {}: {}", descriptor.device_driver.compatible(), x);
} Prevention
- Document which subsystems each post_init callback depends on and enforce registration order.
- Keep post_init callbacks minimal; prefer doing work inside the driver's own init().
- Review descriptors when changing driver registration order.
When it happens
Trigger: A DeviceDriverDescriptor was constructed with Some(post_init_callback) and that closure/function returns Err when called during init_drivers_and_irqs().
Common situations: The callback enables peripherals or registers global state and hits an unmet precondition (IRQ manager not yet set, dependent driver not initialized); the callback was copied from another driver and references wrong hardware; ordering of driver registration changed so a dependency is missing.
Related errors
- Error initializing driver: {}: {}
- Attempt to enable IRQ {} for device {}, but driver does not
- Error during driver interrupt handler registration: {}: {}
- No IRQ Manager registered yet
- Error initializing timer subsystem: {}
AI-assisted analysis of rust-embedded/rust-raspberrypi-OS-tutorials@644474cc09 (2026-09-06).
Data as JSON: /api/errors/896d050607c3e7c2.
Report an issue: GitHub.