Keil µVision Build Errors — What Each Message Means and How to Fix It
Keil µVision reports failures as terse numbered codes, and the first time you see one it is rarely obvious what to change. In practice the same handful of errors come up again and again, and each has a small set of likely causes. This guide walks through them by message: what it means, and the order to check things.
Reading the message
Everything in the Build Output falls into one of a few categories. Knowing which stage failed halves the search space.
| Prefix | Stage | Meaning |
|---|---|---|
#number (e.g. #20, #67) | Compile | C syntax or type problem, inside that .c file |
L6xxx (e.g. L6218E) | Link | Files compiled, but could not be combined |
A1xxx | Assemble | Assembly (.s) problem — usually the startup file |
*** error 65 and similar | Simulator / debugger | Not a build failure at all |
Thirty errors does not mean thirty mistakes. Fix the first one and rebuild — the rest often disappear together.
Link errors — where most people get stuck
L6050U — code size exceeded
Error: L6050U: The code size of this image (xxxxx bytes) exceeds the maximum allowed for this version of the linker.The free MDK-Lite edition caps the output at 32 KB. Nothing is wrong with your code; you hit a licensing limit. To get back under it:
- 1Raise optimisation to
-O2or higher under Options for Target > C/C++. That alone often cuts a lot. - 2
printfand friends pull in kilobytes on their own. Send debug output over UART directly, or enable MicroLIB (Options for Target > Target > Use MicroLIB). - 3Remove drivers and library files the project does not actually use.
- 4If it still does not fit, you need a full licence — the limit cannot be configured away.
L6218E — Undefined symbol
Error: L6218E: Undefined symbol delay_ms (referred from main.o).The linker found the call but not the function body. Check in this order:
- Is the .c file that defines it actually in the project tree? (Including the header but forgetting the .c is the most common cause by far.)
- Do the spelling and case match between declaration and definition?
- Calling a C function from C++? It needs an
extern "C"wrapper. Undefined symbol mainmeans main is missing entirely, or main.c is excluded from the build.
L6236E — No section matches selector
Error: L6236E: No section matches selector - no section to be FIRST/LAST.The startup file (startup_xxx.s) is missing. Add the one matching your device, or tick Device > Startup in Manage Run-Time Environment. Switching target devices and leaving the old startup file behind produces the same error.
Link errors are project-structure problems. Staring at source code will not reveal them — start from the file list in the Project pane.
Compile errors
| Message | Cause | Fix |
|---|---|---|
error: #5: cannot open source input file "stm32f4xx.h" | Header path not registered | Add the folder under Options for Target > C/C++ > Include Paths |
error: #20: identifier "GPIOA" is undefined | Device header missing, or device macro not defined | Check the include, and add the device macro (e.g. STM32F407xx) under Options > C/C++ > Define |
error: #67: expected a "}" | Missing brace or semicolon | Look at the line **before** the reported one |
warning: #1295-D: Deprecated declaration | Old-style declaration | Harmless; give the function explicit parameter types |
error: #513: a value of type ... cannot be assigned | Type mismatch | Cast explicitly between pointers and integers |
If header-not-found keeps coming back, register include paths relative to the project folder rather than as absolute paths. The project then survives being moved to another machine.
When flashing fails
No Algorithm found for: 08000000H - 080003FFH
The build succeeded and the failure is at the programming step: no flash algorithm is registered for your device. Open Options for Target > Debug > Settings > Flash Download, click Add, pick the algorithm for your device family, and check that the start address and size match the part.
Flash Download failed - "Cortex-M4"
- 1Check power and the debug probe (ST-Link / J-Link) first. A charge-only USB cable will not enumerate.
- 2In Debug > Settings, confirm the probe sees the device (an IDCODE appears). If not, it is a wiring problem.
- 3Previously flashed firmware may have disabled the debug pins. Switch to Connect under Reset.
- 4Still stuck: do a full chip erase with ST-Link Utility or STM32CubeProgrammer, then retry.
If another tool (CubeProgrammer, a serial monitor) holds the probe, µVision cannot claim it. Close the other program first.
Simulator errors
*** error 65: access violation at 0x40021000 : no 'read' permissionThis appears when code running in the simulator touches a peripheral register the simulator does not model. It means the simulator does not know that address — not that your code is wrong. Two ways out:
- Switch Options for Target > Debug from the simulator to your actual debug probe and run on hardware.
- To stay in the simulator, map the region from the Debug command line:
MAP 0x40000000, 0x40030000 READ WRITE.
Peripheral behaviour (GPIO, timers) is never fully reproduced in simulation. Use the simulator for logic, and verify hardware behaviour on the board — it saves time in the end.
Still failing — a five-minute checklist
- 1Project > Clean Target, then Rebuild. Stale object files cause phantom errors.
- 2Read only the **first** error in the Build Output and fix that.
- 3Confirm every required .c file is in the Project pane — especially the startup file.
- 4Check Options for Target > Device against the actual part. If you changed devices, change the define macro too.
- 5Open Manage Run-Time Environment and look for yellow or red markers — missing packs show up here.
- 6Move the project somewhere without spaces or non-ASCII characters in the path. Older toolchains still trip over those.
FAQ
Q. Can the 32 KB limit be unlocked in settings?
No — it is a licence condition of MDK-Lite, not a configurable option. For STM32 parts, ST's own STM32CubeIDE is free with no size limit, so moving there is a reasonable option for learning projects.
Q. It builds and flashes, but the board does nothing.
Usually a clock problem: the peripheral clock (RCC) for the port was never enabled. Check that before anything else, then confirm the download actually succeeded and the board was reset.
Q. The reported line number doesn't match my code.
An error raised inside a header is reported at the line that included it. Trust the file name in the message first, and suspect macro expansion if the code is macro-heavy.
Q. The same project builds on another PC.
Most often absolute include paths, or a device pack that is not installed. Match pack versions in Pack Installer and switch include paths to project-relative.