Problem Summary
When writing a Function Block (FB) in STEP 7 for a SIMATIC S7-300 or S7-400 CPU, an engineer declares STAT variables intended to hold System Function Block (SFB) instances. After declaring them, the compiler reports a single, unhelpful line in the diagnostics tab:
The FB will not be saved, downloaded, or executed until this is resolved. The wording is identical whether the fault is a misnamed instance, a wrong SFB number, a missing
STAT declaration, or a corruption of the call interface.This article isolates the four root causes, ranks them by frequency on real engineering projects, and gives a deterministic fix for each. The procedure applies to STEP 7 V5.4 / V5.5 / V5.6 (Classic) and the equivalent TIA Portal block libraries for S7-300/400 firmware images.
Why "Type Conflict" Occurs With SFB Calls
A System Function Block on S7-300/400 is a system-supplied FB with a fixed, non-editable interface. According to the SIMATIC S7-300 Instruction List, the operating system provides SFBs 0-5 unconditionally, and additional SFBs (3-5 timers, 0-2 counters, 32-65 communications, 41-49 closed-loop and counting) depending on the CPU order number. Each SFB expects a private instance that holds its actual parameters (IN, OUT, IN_OUT, STAT) between calls.
An instance can be allocated in one of two places:
- Single instance DB – a stand-alone Instance Data Block tied to the SFB and called directly from OB / FC / FB code.
- Multi-instance – a STAT variable inside another FB. The outer FB's instance DB then holds the working data for every SFB called within it. Multi-instance is the only way to nest SFBs/FBs without creating a new DB for each call.
The compiler raises Type conflict when the type declared for the STAT slot does not match the type of the SFB actually invoked at the call site. STEP 7 does this check at compile time, not at runtime, so the program is blocked before a single network can be tested.
Root Cause Matrix
| # | Root cause | Symptom | Detection |
|---|---|---|---|
| 1 | STAT declared with a generic or wrong type (BOOL, INT, or FBxx instead of SFBxx) | Compiler error on FB save | Open the FB's interface declaration and verify the Type column |
| 2 | SFB number not available on target CPU (e.g. SFB41 on a 312 IFM) | Error 12 even with correct type | Compare SFB list against the hardware catalog |
| 3 | SFB call entered by hand instead of inserted from the program-element browser | Compiler treats the call as a stray instance and rejects the type | View the call in the program-element browser; check that the right pane shows the SFB symbol, not a blank box |
| 4 | Corrupted call interface after editing another FB that is reused as a type | Sporadic 12 errors that disappear after a clean rebuild | Close the project, delete the *.s7p compiler cache, and rebuild |
Cause 1 is responsible for the majority of field cases. Causes 2-4 are common during porting or when a project has been edited across multiple STEP 7 versions.
Prerequisites for a Clean Fix
- STEP 7 V5.4 or later installed with the matching Service Pack for the target CPU firmware.
- The hardware catalog updated (right-click → Update Catalog) so the CPU order number is current.
- The FB must be compiled in the SCL, LAD, or FBD editor that is installed on the engineering station; mixed editors in a single FB are not supported on S7-300/400.
- Know the SFB numbers you actually need; the standard IEC timer/counter set on S7-300 is SFB0-SFB5. Other SFBs (SFB32-PULSEGEN, SFB41-CONT_C, SFB52-RDREC, etc.) are only valid on CPUs that ship with that firmware feature.
Step-by-Step Resolution
Step 1 – Verify the CPU supports the SFB
Open HW Config, double-click the CPU, and read the Order Number / Firmware. Cross-reference it with the Siemens SFB list document. If the SFB is not in the CPU's instruction set, STEP 7 still lets you type the block, but the compiler fails on FB save. The first thing to do is to remove the unsupported SFB and replace it with a standard IEC timer/counter (FB) from the standard library, or upgrade the CPU's firmware.
Step 2 – Declare the STAT variable with the exact SFB type
Open the FB and switch to the Interface view at the bottom of the editor. In the STAT section, add a row with:
| Name | Type | Initial Value | Comment |
|---|---|---|---|
| iTon1 | SFB4 | — | On-delay timer, IEC 1131 |
| iCtu1 | SFB0 | — | Count up |
| iPulse1 | SFB3 | — | Pulse timer |
The Type column is case-sensitive. sfb4 or SFB 4 is rejected. The class of the SFB (the number) must match the block you later call.
Step 3 – Use drag-and-drop to insert the call (recommended)
Open the program-element browser (View > Overview or press Ctrl+K). Navigate to Libraries > Standard Library > System Function Blocks. Click the SFB you want, drag it onto the network in the FB, and drop it directly on top of the STAT instance name. The editor then writes the call symbol, populates the input and output pins, and binds the instance automatically.
This is the only insertion path that produces a self-consistent SFB call. Manually typing CALL SFB 4, iTon1 in the LAD/FBD editor is a frequent source of type mismatches because the editor sometimes binds to the wrong instance or leaves the call as a generic reference.
Step 4 – Wire the actual parameters
Click the SFB box in the network. The IN, OUT, and IN_OUT pins appear automatically. Wire each pin to a local or global symbol (or to a constant for timers / counters). Example for SFB4:
iStart BOOL -- call from logic
PT T#5s
Q -> bDone
ET -> tElapsed TIME
Step 5 – Save and compile
Press Ctrl+S. The compiler must now report zero errors. If the type conflict persists, jump to Cause 4 below.
The "Type Check of Address" Workaround
STEP 7 exposes a single checkbox that suppresses the type-conflict diagnostic in the LAD/FBD editor:
- Open the LAD or FBD editor.
- Menu: Options > Customize > LAD/FBD.
- Uncheck Type Check of Address.
- Click OK and recompile.
With the checkbox cleared, the editor accepts a wider range of mismatches at the call site. The compiler no longer raises error 12 and the FB saves.
Verifying the Fix
-
Static check – In the FB interface, every SFB instance row should show the SFB number in the Type column. Sort the rows by Type and check that no row reads
FBxxxwhen the call is SFBxxx, or vice versa. - Compile – Run Program > Compile (All). The error tab must be empty for the FB and for any instance DBs generated from it.
-
Download – Do a full download to the CPU (not a delta download) so the new instance DB is created. Confirm in the online view that the instance DB exists and that the SFB's internal tags (e.g.
SFB4.CR,SFB4.TV,SFB4.Q) are visible. - Watch table – Add the instance DB to a VAT and force the SFB inputs. The outputs must update on the next OB1 cycle. If the inputs stick at the initial value, the instance was not bound to the DB and the call is reading default state every cycle.
- Reference data – Generate the program structure and confirm that the SFBs in the FB all show their own subtree inside the FB's instance DB.
SFB Reference for S7-300
| SFB No. | Symbolic Name | Function | Minimum CPU |
|---|---|---|---|
| SFB0 | CTU | Count up | All S7-300 / S7-400 |
| SFB1 | CTD | Count down | All S7-300 / S7-400 |
| SFB2 | CTUD | Count up / down | All S7-300 / S7-400 |
| SFB3 | TP | Pulse timer | All S7-300 / S7-400 |
| SFB4 | TON | On-delay timer | All S7-300 / S7-400 |
| SFB5 | TOF | Off-delay timer | All S7-300 / S7-400 |
| SFB32 | PULSEGEN | Pulse-train generator | 31x, 41x, all S7-400 |
| SFB33 | D_ACT_DP | Activate / deactivate DP slave | All S7-400, ET200S |
| SFB35 | ALARM | Generate ACK-relevant alarm | All S7-400 |
| SFB36 | NOTIFY | Generate status message | All S7-400 |
| SFB41 | CONT_C | Continuous PID controller | S7-31xT, all S7-400 |
| SFB42 | CONT_S | Step controller | S7-31xT, all S7-400 |
| SFB43 | PULSEGEN | Pulse generator for PID | S7-31xT, all S7-400 |
| SFB44 | ANALOG | Analog positioner | S7-31xT, all S7-400 |
| SFB46 | DIGITAL | Digital positioner | S7-31xT, all S7-400 |
| SFB47 | COUNT | High-speed counter | CPU 31xC |
| SFB48 | FREQUENC | Frequency measurement | CPU 31xC |
| SFB49 | PULSE | Pulse-width modulation | CPU 31xC |
| SFB52 | RDREC | Read data record | DP/PN CPUs |
| SFB53 | WRREC | Write data record | DP/PN CPUs |
| SFB54 | RALRM | Receive interrupt | PN CPUs |
| SFB73 | PUT | Write to partner CPU (S7 comm.) | All S7-300 / S7-400 |
| SFB74 | GET | Read from partner CPU | All S7-300 / S7-400 |
| SFB81 | RD_DPAR | Read dynamic device parameters | PN CPUs |
The full SFB list with execution times per CPU family is published in the SIMATIC S7-300 Instruction List. Always cross-reference the CPU's order number against the SFB number before declaring the STAT slot.
Special Case – SFBs in S7-1200 and S7-1500
S7-1200 and S7-1500 do not use the SFB naming scheme. The IEC timers and counters are delivered as standard FBs in the STEP 7 (TIA Portal) basic instructions library:
| S7-300/400 SFB | TIA Portal Equivalent (FB) | Notes |
|---|---|---|
| SFB0 CTU | CTU (FB) | Multi-instance supported |
| SFB1 CTD | CTD (FB) | Multi-instance supported |
| SFB2 CTUD | CTUD (FB) | Multi-instance supported |
| SFB3 TP | TP (FB) | Multi-instance supported |
| SFB4 TON | TON (FB) | Multi-instance supported |
| SFB5 TOF | TOF (FB) | Multi-instance supported |
| SFB41 CONT_C | PID_Compact (FB) | Optimized for S7-1200/1500 |
| SFB43 PULSEGEN | Internal to PID_Compact | No external SFB |
If a project is migrated from S7-300 to S7-1500, every STAT declaration of type SFBxx must be re-declared with the new FB type from the TIA Portal library. Otherwise the compiler raises the S7-1500 equivalent of error 12: "The block type is unknown or invalid."
Advanced Diagnostics When the Fix Does Not Stick
Cross-version project corruption
STEP 7 V5.4 SP5+ occasionally corrupts the program-element browser cache when a project is opened alternately in different versions. The symptom is intermittent error 12 that reappears after a full rebuild. Recovery:
- Close the project.
- In the project directory, delete the
imandsfcsubfolders insideGlobal. - Open the project, run Program > Compile (All).
Stub call from copy-paste
When an FB is copied between projects, the SFB call sometimes loses the instance binding. The network still displays a box with the SFB name, but the instance pointer is null. Open the call, re-drag the SFB onto the instance, and rewire.
Know-how protection
Protected FBs (know-how protection) cannot host multi-instance SFBs whose source is also know-how protected. Decompile or request the unprotected source from the OEM before adding a new SFB instance.
Versioned FB reused as a type
When an FB is versioned (FB1 v1.0, v1.1, v1.2), the multi-instance type follows the version. If the calling FB refers to FB1 v1.0 and the SFB sits in FB1 v1.1, the call fails with error 12. Re-pick the version in the Type column.
Related Compiler Messages on S7-300/400
| Code | Message | Likely cause | Action |
|---|---|---|---|
| 10 | Unknown block / FB not found | FB was renamed or removed from project | Re-link the type or restore the FB |
| 11 | Multi-instance is not yet supported | Calling a UDT / ARRAY in STAT instead of a block | Replace the UDT with the appropriate FB/SFB type |
| 12 | Type conflict | Type column does not match the SFB number | Re-declare STAT or re-drag the SFB |
| 14 | Multiple instance DB for FB | Single instance DB is also assigned | Remove the redundant DB link |
| 15 | Instance DB does not exist | DB not generated / not downloaded | Compile the S7 program, then full download |
| 18 | Block exists twice | Same FB / SFB number imported from two sources | Resolve the conflict in the S7 program |
Sample FB Skeleton
A minimal S7-300 FB that calls SFB3 (pulse), SFB4 (on-delay), and SFB0 (counter) as multi-instances, written in FBD notation, is shown below. The interface declarations are the part the compiler actually inspects.
FUNCTION_BLOCK FB_TimerDemo
VAR
bStart : BOOL; // input
bReset : BOOL; // input
tPulse : TIME; // input
tDelay : TIME; // input
bDone : BOOL; // output
wCount : WORD; // output
END_VAR
VAR STAT
iPulse1 : SFB3; // pulse timer
iTon1 : SFB4; // on-delay timer
iCtu1 : SFB0; // count up
END_VAR
BEGIN
// pulse timer (SFB3)
iPulse1(IN := bStart, PT := tPulse);
// on-delay timer (SFB4), enabled by pulse end
iTon1(IN := iPulse1.Q, PT := tDelay);
bDone := iTon1.Q;
// count up on every rising edge of bDone
iCtu1(CU := bDone, R := bReset, PV := INT#100);
wCount := iCtu1.CV;
END_FUNCTION_BLOCK
The instance data for the three SFBs lives in the FB's instance DB (one DB per call of the outer FB). No separate DBs per SFB are required.
Field-Proven Caveats
FAQ
Why does the compiler say "Type conflict" only on SFBs and not on FBs I call?
FB types are project-owned, so STEP 7 trusts whatever type the user enters. SFBs are system-owned, so the compiler compares the declared type against the operating-system catalogue. A typo in the SFB number, or an SFB the CPU firmware does not provide, fails this check. FBs do not.
Can I declare two multi-instances of the same SFB inside one FB?
Yes. Multi-instance is exactly that pattern. Add two STAT rows, e.g. iTon1 : SFB4 and iTon2 : SFB4, drop the SFB on each row, and STEP 7 allocates a separate slot in the instance DB for each. The two timers run independently and the FB still uses only one instance DB.
Is it safe to uncheck "Type Check of Address" in the LAD/FBD editor?
It is safe for a one-shot confirmation that error 12 is a STEP 7 false positive. It is not safe as a long-term project setting. With the check off, real interface mismatches (e.g. wiring an INT to a TIME pin) compile cleanly and only fail at runtime as parameter overwrites, which are far more expensive to find.
Why does my migrated S7-300 project fail in TIA Portal with the same error?
S7-1200 and S7-1500 do not have SFB0-SFB5 in the same form. The IEC timers/counters are FBs in the TIA Portal basic-instructions library. After migration, re-declare every STAT slot with the new FB type (e.g. CTU, TON) and rewire the call. The behaviour is functionally identical.
Does the same fix apply to S7-400 with FBs containing SFB41 (CONT_C) and SFB42 (CONT_S)?
Yes. Declare iPid1 : SFB41 in STAT, then drag SFB41 from the standard library onto the call. If the CPU is a 412 or 414, SFB41/42/43/44/46 are available; on 410, none of them are. Check the CPU order number first.