Fix it now
Microsoft publishes 48 as “Error in loading code resource or DLL” and 53 as “File not found”. Neither is about the file you opened: a library the project references has moved, changed architecture or gone. VBA compiles a project as a unit, so one broken reference stops every macro in it.
- Open the Visual Basic editor with Alt+F11, then Tools > References.
- Look at the top of the list for entries prefixed MISSING. Write down each name and the path shown against it before you change anything, then untick them.
- Run Debug > Compile VBAProject. The project has to compile cleanly before any macro will run.
- If compiling now reports an undefined name that used to work, the reference you unticked supplied it. Tick the current version of the same library, or rewrite that call to use late binding.
- If Declare statements are involved, confirm each carries PtrSafe and that arguments holding a handle or a pointer are declared LongPtr rather than Long.
- Close every Office application, then clear the cached control files with a .exd extension from the Forms cache in your profile and from the Office temporary folders, and reopen.
Do not untick a reference you cannot identify. Recovering a lost reference from a stripped project means working out which library supplied each undefined name, one at a time.
If the project compiles and the macros run, you are done. The next section explains what a reference actually is and why one broken one takes everything with it.
Why it happens
A VBA project does not embed the libraries it uses. It stores a pointer to each one: a class identifier, a version, and the path where that library was registered when the project was written. At load time VBA resolves each pointer through the registry. If the entry has gone, or the recorded version no longer exists, the reference resolves to nothing and the editor lists it as MISSING.
The consequence is out of all proportion to the cause, because VBA compiles a project as a single unit. One unresolved reference stops the whole thing, so macros with no connection to the missing library fail, buttons stop responding, and the user reports that every macro broke at once. The published messages describe the layers: 48 is a code resource or DLL that could not be loaded, 53 is a file that was not found, 432 is a file or class name that could not be resolved during an automation operation, and 35 is the compiler reaching a Sub, Function or Property that is not defined because the library that supplied it is gone.
Two more are worth recognising. 49 is “Bad code resource or DLL calling convention”, which is what a Declare statement produces when the declaration does not match the function it is calling. 0x8007007E is Windows error 126, ERROR_MOD_NOT_FOUND, “The specified module could not be found” – and it can mean the library itself is missing or a dependency it in turn needs is. Chasing the named file when the real gap is one level below it is a classic waste of an afternoon.
A reference is marked MISSING after an update or a rebuild
You have this one if Tools > References shows entries prefixed MISSING, and the path shown points somewhere that no longer exists.
- Record the name and path of every MISSING entry, then untick them and click OK.
- Run Debug > Compile VBAProject. Every place the removed library was used now raises an undefined name, which tells you exactly what depended on it.
- Tick the current version of the same library if it is in the list, compile again, and save the file once it is clean.
The project is bound to a newer library than this machine has
You have this one if The file works on the machine it was written on and fails on older Office builds.
- Develop against the oldest Office version in the estate. References record the version they were made against and do not resolve downward.
- Where you cannot control that, convert the affected calls to late binding: declare the variable As Object and create it with CreateObject.
- Keep an early-bound copy for development, and compile on a machine matching the lowest target build before you ship.
Architecture mismatch between Office and the component
You have this one if It works on 32-bit Office and fails on 64-bit, or fails straight after an in-place upgrade.
- Confirm the build at File > Account > About.
- An in-process component has to match the host’s architecture. Get a matching build from the vendor, or replace the control with a native one.
- Add PtrSafe to every Declare and change handle and pointer arguments to LongPtr, which resolves to Long on 32-bit Office and LongLong on 64-bit.
- Where one file must serve both, wrap the declarations in conditional compilation using the VBA7 and Win64 constants.
Adding PtrSafe alone is not enough. Microsoft states it only asserts that the Declare targets 64-bit; every data type that needs to hold 64 bits still has to be changed, and leaving those as Long produces crashes rather than clean errors.
The component was never registered on this machine
You have this one if It fails on newly built machines and for new starters, and works everywhere it has been for years.
- Identify the component from the path shown against the MISSING reference.
- Install it with its own installer where one exists, which is always better than copying a file and registering it by hand.
- Where it ships only as a control file, register it from an elevated prompt with the utility matching the component’s architecture, then add it to your standard build.
Stale control cache files after an update
You have this one if Forms fail to open or report an invalid object library, and it hit many machines on the same day.
- Close every Office application and confirm no Office process is still running.
- Delete the cached files with a .exd extension from the Forms cache in the user profile and from the Office temporary folders.
- Reopen the file. The caches rebuild from the currently registered controls, so if this recurs after updates, script the clearance into your update routine.
Microsoft publishes nothing we could verify about this step, but the files are caches rather than configuration: the only cost of deleting them is the moment they take to rebuild.
Full reference
Telling the failures apart
| Symptom | Most likely layer |
|---|---|
| MISSING shown against a reference | The library is not registered here, or not at that version |
| Fails only on 64-bit Office | A component with no 64-bit build, or a Declare without PtrSafe and LongPtr |
| A form will not open and reports an invalid object library | Stale control cache files need clearing |
| Fails on new machines, works on the developer’s | A component installed by software only the developer has |
| Everything fails, including macros that touch nothing unusual | The project will not compile, which is what a single MISSING reference does |
Writing a Declare that works on both architectures
#If VBA7 Then
#If Win64 Then
Private Declare PtrSafe Function GetTickCount64 Lib "kernel32" () As LongLong
#Else
Private Declare PtrSafe Function GetTickCount Lib "kernel32" () As Long
#End If
#Else
Private Declare Function GetTickCount Lib "kernel32" () As Long
#End If
VBA7 tests whether the code is running in the newer editor; Win64 tests whether the Office running it is 64-bit. They are two different questions and both are needed, because a 64-bit Office always has VBA7 but a VBA7 editor is not always 64-bit. Microsoft states that an unmodified Declare on 64-bit Office produces an error saying the statement does not include the PtrSafe qualifier, which is the compile-time symptom to expect.
LongPtr, and why it is not just a rename
- LongPtr resolves to Long on 32-bit Office and to LongLong on 64-bit Office. Use it for pointers and handles.
- PtrSafe asserts the declaration has been reviewed for 64-bit. It does not convert anything.
- A handle left as Long on 64-bit is truncated, which corrupts memory rather than raising an error. That is why the failures look like crashes.
- Return values need the same treatment as arguments, and are the ones most often forgotten.
Reference hygiene that stops this recurring
- Develop on the lowest Office build in use, so references never record a version your users do not have.
- Prefer native controls to third-party ones wherever a native equivalent exists.
- Use late binding for anything version-sensitive, and keep the project compiling under early binding while you develop.
- Compile with Debug > Compile before every release, not just when something breaks.
- Test on a machine built from your standard image before an update goes out widely.
Registering or unregistering a control writes to the registry and affects every application on the machine, not only Office. Export the relevant branch or take a restore point first, and never unregister a component other software may be using.
Every code this article covers
| Code | What it points at | Source |
|---|---|---|
48 |
Error in loading code resource or DLL | Microsoft Learn |
53 |
File not found | Microsoft Learn |
35 |
Sub, Function, or Property not defined | Microsoft Learn |
0x8007007E |
Windows error 126, ERROR_MOD_NOT_FOUND: the specified module could not be found – which may be the library or a dependency of it | Microsoft Learn |
49 |
Bad code resource or DLL calling convention | Microsoft Learn |
432 |
File name or class name not found during Automation operation | Microsoft Learn |
Confirm the fix worked
- Run Debug > Compile VBAProject and confirm it completes without stopping.
- Reopen Tools > References and confirm no entry is marked MISSING.
- Close Office entirely, reopen the file and run the macro from a cold start rather than from the editor.
- Open every form in the project, because form failures show up separately from module failures.
- Test on a second machine built from your standard image, not on the developer’s workstation.
Questions people ask about this
Is this a licensing problem? Do I need to buy anything?
No, and it costs nothing to resolve. Broken references are a configuration and packaging problem rather than an entitlement one. The only money that could be involved is buying a 64-bit build of a third-party control from its own vendor, which is a matter for them rather than for your Office licence.
Should I switch everything to late binding?
It is a reasonable habit for code that must run across mixed Office versions, and it removes this class of failure entirely. The cost is that mistakes surface at run time instead of at compile time, so keep the project compiling cleanly under early binding while you develop.
Why did all the macros stop, not just the one using the missing library?
VBA compiles the project as a single unit. An unresolved reference stops compilation, and nothing in a project that will not compile can run – including code that never touches the missing component.
Is adding PtrSafe enough to make old code work on 64-bit Office?
No. Microsoft is explicit that PtrSafe only signifies the Declare statement targets 64-bit; every data type that needs to hold a 64-bit value, including return values, still has to be changed. Leaving a handle as Long produces a truncated pointer and a crash rather than a clean error.
Can I stop this happening after every update?
Mostly. Develop on the lowest build in use, avoid third-party controls where a native equivalent exists, use late binding for anything version-sensitive, and test on a representative machine before an update goes out widely.
