Checked Build ASSERTs

This topic contains a list of common ASSERTs encountered by driver writers.

For some tips on how to handle these asserts (and others not listed), see How the Checked Build Indicates a Problem.

The routine listed in the "Routine Called" column is the most common routine that driver writers or system components would call to provoke this error. Some of the routines listed below are documented routines that drivers call. Others are internal routines that only system components can call. Keep in mind that calling some other function from your driver might result in the called function internally calling one of the listed functions, which could in turn issue the ASSERT.

Note

Checked builds were available on older versions of Windows, before Windows 10 version 1803. Use tools such as Driver Verifier and GFlags to check driver code in later versions of Windows.

Routine Called ASSERT text Meaning

IoAllocateMdl

ASSERT(Length)

The length of the user buffer being described is zero.

IoAttachDeviceToDeviceStack

ASSERT( sourceExtension->AttachedTo == NULL )

The device object that is being attached (the source device) is already attached to another device object.

IoCallDriver

ASSERT( Irp->Type == IO_TYPE_IRP )

The PIRP argument does not point to an IRP.

IoCancelIrp

ASSERT( Irp->Type == IO_TYPE_IRP )

The PIRP argument does not point to an IRP.

IoCompleteRequest

ASSERT( Irp->Type == IO_TYPE_IRP )

The PIRP argument does not point to an IRP.

IoCompleteRequest

ASSERT( !Irp->CancelRoutine )

There is a cancel routine present in the IRP.

IoCompleteRequest

ASSERT( Irp->IoStatus.Status != STATUS_PENDING )

An attempt to complete an IRP with STATUS_PENDING.

IoCompleteRequest

ASSERT( Irp->IoStatus.Status != 0xffffffff )

An attempt to complete an IRP with an invalid status code.

IoCompleteRequest

ASSERT( Irp->Tail.Overlay.AuxiliaryBuffer != NULL )

An IRP is being completed with STATUS_REPARSE, IO_REPARSE_TAG_MOUNT_POINT, and the auxillary buffer is NULL.

IoCreateDevice

ASSERT((DriverObject->Flags & DRVO_UNLOAD_INVOKED) == 0)

A device object has been created, but the driver creating it is marked for unload.

IoFreeIrp

ASSERT( Irp->Type == IO_TYPE_IRP )

The PIRP does not point to an IRP.

IoFreeIrp

ASSERT(IsListEmpty(&(Irp)->ThreadListEntry))

The IRP being freed is still on a thread's IRP list, and therefore still in use.

IoFreeIrp

ASSERT( Irp->CurrentLocation >= Irp->StackCount )

An IRP is being freed, but I/O completion has not yet finished for all drivers that processed this IRP.

IoReuseIrp

ASSERT(Irp->CancelRoutine == NULL)

There is a cancel routine remaining in the IRP that is been requested to reuse.

IoReuseIrp

ASSERT(IsListEmpty(&Irp->ThreadListEntry))

The IRP being reused is still on a thread's IRP list, and therefore still in use.

IoSetHardErrorOrVerifyDevice

ASSERT( Irp->Tail.Overlay.Thread != NULL )

The IRP is not on any thread's IRP list.

IopLoadDriver

ASSERT(driverObject->MajorFunction[i] != NULL)

The driver set a dispatch entry point to NULL in its DriverEntry routine.

IopCompleteRequest

ASSERT( irp->IoStatus.Status != 0xffffffff)

An IRP was completed with an obviously invalid status.

IopCompleteRequest

ASSERT(reparseBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)

An IRP was completed with Status == STATUS_REPARSE and Information == IO_REPARSE_TAG_MOUNT_POINT, but the ReparseTag is not for a MOUNT_POINT.

IopCompleteRequest

ASSERT(reparseBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE)

An IRP was completed with Status == STATUS_REPARSE and Information == IO_REPARSE_TAG_MOUNT_POINT, but the returned tag has an invalid length.

IopCompleteRequest

ASSERT(reparseBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE)

An IRP was completed with Status == STATUS_REPARSE and Information == IO_REPARSE_TAG_MOUNT_POINT, but the returned tag has an invalid length.

IopSynchronousServiceTail

ASSERT( !Irp->PendingReturned )

An IRP was marked pending, but synchronously dispatch routine returned with status != STATUS_PENDING.

MmProbeAndLockPages

ASSERT (MemoryDescriptorList->ByteCount != 0)

The byte count in the passed-in MDL is zero.

MmProbeAndLockPages

ASSERT (((ULONG)MemoryDescriptorList->ByteOffset & ~(PAGE_SIZE - 1)) == 0)

The offset into the first page in the MDL is >= PAGE_SIZE; the MDL is incorrectly formed.

MmProbeAndLockPages

ASSERT (((ULONG_PTR)MemoryDescriptorList->StartVa & (PAGE_SIZE - 1)) == 0)

The starting VA in the MDL is not page aligned; the MDL is incorrectly formed.

MmProbeAndLockPages

ASSERT ((MemoryDescriptorList->MdlFlags & ( MDL_PAGES_LOCKED | MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL | MDL_PARTIAL | MDL_IO_SPACE)) == 0)

The MDL is not in proper state for this function call.

MmProbeAndLockPages

ASSERT (NumberOfPagesToLock != 0)

The MDL describes a range of pages with zero pages to lock.

MmProbeAndLockPages

ASSERT (FALSE)

A page in the buffer described by the MDL has been locked into memory an unusually high number of times.

MmUnlockPages

ASSERT ((MemoryDescriptorList->MdlFlags & MDL_PAGES_LOCKED) != 0)

The pages that comprise the buffer described by this MDL have not been locked.

MmUnlockPages

ASSERT ((MemoryDescriptorList->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0)

The MDL describes a buffer from nonpaged pool.

MmUnlockPages

ASSERT ((MemoryDescriptorList->MdlFlags & MDL_PARTIAL) == 0)

The MDL was built by calling IoBuildPartialMdl.

MmUnlockPages

ASSERT (MemoryDescriptorList->ByteCount != 0)

The MDL describes a buffer that is zero bytes long.

MmUnlockPages

ASSERT (NumberOfPages != 0)

The MDL does not contain any pages.

MmUnlockPages

ASSERT ((SPFN_NUMBER)Process->NumberOfLockedPages >= 0)

The process associated with the MDL does not have any pages locked.

MmUnlockPages

ASSERT (Page <= MmHighestPhysicalPage)

A page frame pointer in the MDL is not valid.

MmBuildMdlForNonPagedPool

ASSERT (MemoryDescriptorList->ByteCount != 0)

The buffer described by the MDL is zero bytes long.

MmBuildMdlForNonPagedPool

ASSERT ((MemoryDescriptorList->MdlFlags & (MDL_PAGES_LOCKED | MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL | MDL_PARTIAL)) == 0)

The MDL is not in a proper state for this function call

MmBuildMdlForNonPagedPool

ASSERT (NumberOfPages != 0)

The MDL describes a buffer with zero pages.

MmMapLockedPagesSpecifyCache

ASSERT (MemoryDescriptorList->ByteCount != 0)

The MDL has zero length.

MmMapLockedPagesSpecifyCache

ASSERT ((MemoryDescriptorList->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0)

The buffer described by this MDL is already mapped into kernel virtual address space.

MmMapLockedPagesSpecifyCache

ASSERT ((MemoryDescriptorList->MdlFlags & ( MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL | MDL_PARTIAL_HAS_BEEN_MAPPED)) == 0)

The MDL is not in a proper state for this function call.

MmMapLockedPagesSpecifyCache

ASSERT ((MemoryDescriptorList->MdlFlags & ( MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0)

The MDL is not in a proper state for this operation.

MmMapLockedPagesSpecifyCache

ASSERT (PointerPte->u.Hard.Valid == 0)

The buffer described by the MDL contains a page that is not resident in memory.

MmMapLockedPagesSpecifyCache

ASSERT (Pfn2->u3.e2.ReferenceCount != 0)

The buffer described by the MDL contains a page that is not locked in memory.

MmUnmapLockedPages

ASSERT (MemoryDescriptorList->ByteCount != 0)

The MDL describes a buffer that is zero bytes long.

MmUnmapLockedPages

ASSERT (MemoryDescriptorList->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)

The parameter passed to this function to specify the base address indicated an address in kernel virtual address space, but this does not agree with the buffer description in the MDL.

MmUnmapLockedPages

ASSERT (PointerPte->u.Hard.Valid == 1)

A page in the buffer described by the MDL is not resident in memory.

MmUnmapLockedPages

ASSERT (Page == MI_GET_PAGE_FRAME_FROM_PTE (PointerPte))

A page frame pointer in the MDL is not valid.

MmUnmapLockedPages

ASSERT (Pfn3->u3.e2.ReferenceCount != 0)

The buffer described by the MDL contains a page that is not locked in memory.

MmMapIoSpace

ASSERT (PhysicalAddress.HighPart == 0)

This is running on an x86-based system with not more than 4 GB of physical memory, but the parameter passed to this function to specify the high 32 bits of the I/O space address is nonzero.

MmMapIoSpace

ASSERT (NumberOfBytes != 0)

The parameter passed to this function to specify the number of bytes to map is zero.

MmMapIoSpace

ASSERT (PointerPte->u.Hard.Valid == 0)

A page in the address rage is not in I/O space.

MmUnmapIoSpace

ASSERT (NumberOfBytes != 0)

The parameter passed to this function to specify the number of bytes to unmap is zero.

MmAllocateContiguousMemory

ASSERT (NumberOfBytes != 0)

The parameter passed to this function to specify the number of bytes to allocate is zero.

MemorySpecifyCache

ASSERT (NumberOfBytes != 0)

The parameter passed to this function to specify the number of bytes to allocate is zero.

MmAllocateNonCachedMemory

ASSERT (NumberOfBytes != 0)

The parameter passed to this function to specify the number of bytes to allocate is zero.

MmFreeNonCachedMemory

ASSERT (NumberOfBytes != 0)

The parameter passed to this function to specify the number of bytes to free is zero.

MmFreeNonCachedMemory

ASSERT (PAGE_ALIGN (BaseAddress) == BaseAddress)

The parameter passed to this function to specify the base address is not valid.