The block looks incomplete, as if cut off halfway.
An accidental edit at the machine or an interrupted transfer. Confirm it against the server copy. Fix it by reloading the whole program rather than patching the line, in case there is more damage.
We use technical and security cookies and, only if you accept, analytics with no cross-site tracking. More in the Cookie policy and Privacy policy.
We use first-party cookies and technical storage to make the site work, Google reCAPTCHA security technology and, only if you accept, Vercel analytics (no cookies, no cross-site tracking). You can accept or reject analytics; both options are equivalent and you can change your choice at any time. More info: Cookie policy, Privacy policy, Legal notice and Terms and conditions.
There is a subprogram call with no indication of which subprogram to call, or with that address written wrongly. The control meets the jump instruction and has no destination. It is a pure program error and it is fixed in the block, but it is worth understanding why it appears, because it is hardly ever an isolated slip.
For reference only: alarms change with the manufacturer, the control and the machine PLC. Check the full code in the official manual before doing anything. Legal notice.
If it occurs in multiple valid programs or after a change of control.
Reset after fixing the block.
Choose the manual matching your control series, software version and machine builder. A support portal is a starting point; it does not establish applicability to every model.
When the interpreter reads a subprogram call, it expects to find in the same block the address identifying the destination and, optionally, the number of repeats. That address is mandatory: without it the instruction is incomplete and the control has no basis for deciding where to jump, so it aborts before doing anything. The interesting part is how you end up with a block like that. Somebody rarely writes a call and forgets the destination from scratch; what usually happens is that the block was left half-edited, that a find-and-replace on the PC took out part of the line, that the transfer was cut off right there, or that the original block carried the number in a macro variable that has no value at run time. That last case is the most interesting: in programs that build the call from a variable, if the variable arrives empty because it was not passed as an argument or was never initialised, the control sees a call with no valid destination and complains exactly as if it had never been written. So when the block looks complete on screen and it still fails, look at the variable values at run time and not only at the text.
In order, from the fastest and cheapest check to the most expensive.
01Read the whole block where it stopped
Check whether the destination address is present and correctly written, with digits and no odd characters. Also look for anything stuck to it that should not be there, such as leftovers from a previous edit. Most cases are visible at a glance.
02Compare against other calls in the same program
If the program has other subprogram calls that do work, put them side by side. The difference in format between the failing one and the working ones points at the error immediately, and it also tells you what the correct form is on that machine.
03If the destination comes from a variable, look at its value
On the macro variable screen, check what the variable supplying the number holds at the moment of the failure. If it is empty or zero, the problem is not the block: the variable never arrived. Review the macro call and its arguments.
04Compare against the server copy
Open the original program and look at that same block. If it is complete in the original and not at the machine, there was an accidental edit or a corrupt transfer, and it is worth reviewing the rest of the file, not just that line.
05Review the post processor if it repeats
If the same failure appears in several programs from the same CAM system, the post is emitting the call wrongly. Fixing it there stops the scene repeating every week. The clue is that the error always lands on the same kind of operation.
06Fix it and validate from the top
Correct the block, go back to the start of the program and dry run at least until you are past the call, checking that it enters the right subprogram. A corrected call with the wrong number gives no alarm: it runs something else, which is worse.
An accidental edit at the machine or an interrupted transfer. Confirm it against the server copy. Fix it by reloading the whole program rather than patching the line, in case there is more damage.
The variable arrives empty because it was not passed as an argument or was never initialised. Confirm it by looking at the variable screen at the moment of the failure. Fix it in the logic of the program that builds the call.
The post emits the call wrongly for that kind of operation. It is confirmed because the pattern repeats in the same place. Fix it in the CAM system and re-post, not block by block at the machine.
A master copy of every program on the server and the habit of reloading from it when corruption appears, instead of patching. Editing only with plain-text editors or at the control itself. Macros that check their arguments on entry and stop with a clear message if one is missing, rather than failing later with a cryptic alarm. A dry run of every new program. And review the post as soon as the same error appears twice: the second time it is no longer a coincidence.
Fanuc detects an M98 call without the P address or with an invalid P. It is an alarm from the Program area, and in the catalog it is listed as “P address not defined (M98)”. On the machine you notice it like this: Fails when executing M98, The subprogram is not called, It occurs on a specific line.
On the shop floor it almost always comes from one of these causes: M98 without P, P in the wrong format, Referenced subprogram misspelled, Misconfigured post. Rule out the most likely one on your machine first, before touching parameters or swapping anything.
Reset after fixing the block. Resetting without fixing the cause first only hides the problem: PS0076 trips again and, in the meantime, you keep working with the machine in bad shape.
With the machine stopped and in a safe state, start with these checks: Check line with M98, Validate M98 P<number> format, Check the post-processor. That alone will tell you whether it is the program or whether you need to raise a maintenance job.
With PS0076 active, avoid this: Do not delete M98, which is needed, Do not edit halfway without verifying call. Skipping any of these points is what turns a minor stop into an expensive breakdown.
If it occurs in multiple valid programs or after a change of control. If you are not sure how far it goes, stop the machine and report it: a repeat alarm always works out cheaper than a crash.
It is a stop alarm: the cycle will not continue until you fix the cause. It does not always mean serious damage, but it leaves the machine where it is and you have to check it before running again. Guidance reference. Always confirm the full text in the exact machine/control manual.
List of G and M Codes for CNC Programming. Search and filter ISO commands by control, machine or function.
CNC IDE: editing with G/M tooltips, line inspector, conversion between controls and 2D/3D toolpath.
Estimate CNC turning and milling cycle time from G-code. Calculate parts per hour with a breakdown of cutting, rapids, canned cycles and tool changes.