Resolving SFB Type Conflict Error in Siemens S7-300 Function

David Krause13 min read
S7-300SiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

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:

Compiler message 12: Type conflict
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

  1. STEP 7 V5.4 or later installed with the matching Service Pack for the target CPU firmware.
  2. The hardware catalog updated (right-click → Update Catalog) so the CPU order number is current.
  3. 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.
  4. 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:

  1. Open the LAD or FBD editor.
  2. Menu: Options > Customize > LAD/FBD.
  3. Uncheck Type Check of Address.
  4. 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.

Warning: This is a diagnostic suppression, not a fix. The SFB still has to be declared with the correct type in the interface, the call still has to point at a real instance, and the runtime behaviour is unchanged. Use the checkbox only to confirm that error 12 is a STEP 7 false positive, then re-enable it. Long-term projects with the checkbox off accumulate latent interface bugs that surface as parameter overwrites in production.

Verifying the Fix

  1. 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 FBxxx when the call is SFBxxx, or vice versa.
  2. Compile – Run Program > Compile (All). The error tab must be empty for the FB and for any instance DBs generated from it.
  3. 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.
  4. 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.
  5. 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:

  1. Close the project.
  2. In the project directory, delete the im and sfc subfolders inside Global.
  3. 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

SFB31 (NOTIFY_8p) and SFB34 (ALARM_8p) are S7-400 only and were removed from some S7-400 CPU firmware revisions. They are still in the standard library as compile-time types, so a STEP 7 build may succeed offline but fail to download to the target. The compiler does not warn about firmware version mismatches; the diagnostic surfaces only at download time.
Multi-instance in optimised FBs is not a concern on S7-300/400 because the Optimised Block Access attribute is a TIA Portal (S7-1200/1500) feature. On S7-300/400 the multi-instance works the same regardless of the access mode selected for the instance DB.
Re-entrancy: SFBs are not re-entrant. Calling the same SFB from inside a higher-priority OB while it is already running produces undefined state. S7-300/400 do not run the same SFB twice in parallel because OB priority is enforced, but the same multi-instance reused in two OBs with the same priority is still undefined. Use single instances for cross-OB timers.
Step 7 V5.4 vs V5.5: The drag-and-drop of SFBs onto multi-instances was buggy in V5.4 SP1 and SP2. Apply at least SP3, ideally V5.5 with the latest hotfix, before relying on the drag-and-drop method in a production project.

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.

Back to blog