TIA Portal V13: Resolving Address Not Occupied by a Tag Warning

David Krause10 min read
SiemensTIA PortalTroubleshooting
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 Description

When compiling STL, FBD, or LAD logic in TIA Portal V13 / STEP 7 V13 against an S7-300 (or compatible S7-400) CPU, the compiler emits the diagnostic "The address is not occupied by a tag". The message is treated as a warning, not an error, so the program still loads, runs, and exchanges I/O — but the message pollutes the compile output, blocks clean builds in CI pipelines, and frequently indicates that the FB/FC is touching local stack (L-stack) memory that was never explicitly declared in the block interface.

Typical triggers observed in the field:

  • Direct L 0.0, L 20.0 operand references inside an FC or FB without a matching Temp declaration.
  • Migrated legacy STEP 7 V5.x code that used absolute L-stack addresses for scratch storage.
  • Code pasted from a third-party library where the original block interface was stripped.
  • Use of the old OPN %DB10 / DBW0 pair without an explicit L %DB10.DBW0 prefix in the network.

Symptom signature in the inspector window:

[Warning] Block FC100 / Network 7
  The address is not occupied by a tag. 
  Operand: L0.0
  Block: FC100 - "Calc_Phase"

Why the Warning Exists

The TIA Portal V13 compiler enforces IEC 61131-3 symbolic consistency on the S7-300/400 platform. Every memory operand in a code block should resolve to a declared symbol in one of three interface sections:

Section Scope Persisted? Indexed?
Input Caller-supplied No By name only
Output Caller-visible No By name only
InOut Caller-supplied & visible No By name only
Static (FB only) Instance DB-backed Yes (in instance DB) Yes, via multi-instance or ARRAY
Temp Local stack (L-stack) No — cleared each call Yes, via temporary variables
Constant Read-only literal No No

When the compiler encounters an operand such as L0.0, it has no symbol to map to, so it raises the warning. The address is technically valid on the CPU — the L-stack is always present and addressable from 0.0 through the configured local data size (default 256 bytes on S7-300 CPUs) — but the absence of a declaration means the compiler cannot type-check, optimize, or warn about overlap with neighboring temporary variables. This is the exact failure mode the warning is designed to catch.

Field note: S7-300/400 CPUs allocate local stack space per execution level (OB1, OB35, FCs, FBs). If two blocks called in the same priority class both write to L0.0 without coordination, runtime data corruption occurs. The warning is your only static-analysis hint that this risk exists.

Affected Versions and Platforms

Controller Effect AT overlay support Slicing support
S7-300 (all MLFBs) Warning present, no IEC 61131-3 check bypass for L-stack SCL only, local-scope only Not available
S7-400 Warning present, IEC check is configurable per block SCL only, local-scope only Not available
S7-1200 / S7-1500 Warning is normally absent because absolute L addressing is disallowed at the editor level Full SCL scope Full slice support ("Tag".%X0)
ET 200SP / ET 200MP CPUs Same as S7-1500 line Full SCL scope Full slice support

Confirmed in TIA Portal V13.0, V13.1, and the V13.1.4 service pack — the warning is generated even when the project option IEC checks is deselected at the block properties. It is not a per-block toggle.

Root Cause Analysis Flow

  1. Open the Inspector > Compile tab and double-click the warning line. TIA Portal highlights the offending network and operand.
  2. Right-click the block in the project tree and select "Go to > Block interface".
  3. Switch to the Temp row. Confirm whether any Temp variable is defined.
  4. If empty, the absolute operand is the cause. If a temp exists, verify the symbol is used (not the absolute address) in the code.
  5. For migrated V5.x code, compare the V5.5 AWL source against the TIA import. The importer does not generate Temp declarations for raw L-stack references.

Solution 1 — Declare a Temp Variable (Recommended)

The cleanest fix is to give every L-stack operand a symbolic home. Open the block interface, scroll to Temp, add a new row, and select a type that matches the operand width.

  1. Open the FC/FB editor in TIA Portal V13.
  2. In the interface pane, click the Temp section header.
  3. Insert a new row, e.g. Name: PhaseFlag, Data type: Bool.
  4. Compile the block. The compiler assigns the variable to offset 0.0 by default.
  5. Replace every literal L 0.0 reference in the code with the symbol #PhaseFlag.
  6. Recompile — the warning disappears.
// Before (raises warning)
A   L 0.0
=   L 0.0

// After (clean compile)
A   #PhaseFlag
=   #PhaseFlag
Tip: When more than one L-stack byte is touched, declare separate temps rather than one wide variable. The TIA compiler does not always preserve the same offset order you wrote in V5.x, so a single WORD temp may not overlay the bits the legacy code expected.

Solution 2 — Use the AT Construct in SCL

For blocks authored in SCL, the AT overlay lets a derived view reinterpret the byte layout of an existing variable. This is the only way on S7-300/400 to obtain a sliced view, and the overlay is local to the block — it cannot be exported.

FUNCTION_BLOCK "FB_TempOverlay"
VAR
    RawWord : WORD;    // Static, persisted in instance DB
END_VAR
VAR_TEMP
    AT_View  : AT  %DB."FB_TempOverlay".RawWord : ARRAY[0..1] OF BOOL;
END_VAR
BEGIN
    // AT_View[0] corresponds to bit 0 of RawWord
    AT_View[0] := TRUE;
END_FUNCTION_BLOCK

Reference documentation for the AT construct and the S7-300/400 limitations is the Siemens FAQ "How do you program the overlapping of tags with the keyword AT in the TIA Portal?" (entry ID 57132240).

Solution 3 — Apply the Global Message Filter

If the warning is deemed acceptable (e.g. during migration cleanup), it can be suppressed globally through the message filter. TIA Portal V13 does not expose a per-message toggle, so this silences every warning of the same category.

  1. Compile the block.
  2. In the Inspector > Compile tab, right-click the warning row.
  3. Select "Filter messages of this type" — or click the yellow exclamation mark icon in the toolbar to open the full filter dialog.
  4. Uncheck "Warning" to hide all warnings, or expand the category and deselect the specific Address rule.
  5. Confirm with OK and recompile.
Caution: This filter is a view setting, not a compiler directive. It does not change the generated code. The warning still exists in the compiler's output stream and will reappear in any external build log (e.g. TIA Portal Openness, command-line compile, or third-party CI tool that parses the SCL/STL compile XML).

Solution 4 — Restructure Absolute L-Stack Usage

For long-standing legacy blocks where the original programmer intended raw scratch memory, restructure into a typed temp block:

FUNCTION "FC_Scratch" : VOID
VAR_TEMP
    tByte0  : BYTE;      // offset 0.0 - 0.7
    tByte1  : BYTE;      // offset 1.0 - 1.7
    tWord0  : WORD;      // offset 2.0 - 3.7
    tBool0  : BOOL;      // bit inside tByte0 if needed
        bFlag AT %LW2 : BOOL;  // overlay view in SCL only
END_VAR
BEGIN
    // tByte0, tByte1, tWord0 are now symbolic
END_FUNCTION

This pattern is the recommended migration path for AWL code imported from STEP 7 V5.5. After the restructure, no L-stack address is referenced literally, and the IEC check can be re-enabled.

Solution 5 — Replace OPN DB / DBW0 Pairs

A second common warning in migrated code is the use of OPN %DB10 followed by L DBW0. Replace with a fully-qualified operand:

// Legacy pattern (raises warnings in TIA V13)
OPN   %DB10
L     DBW0
T     %MW100

// TIA-clean replacement
L     %DB10.DBW0
T     %MW100

The fully-qualified form is the only one the V13 STL editor accepts without warning. The DB must be present in the project, compiled without error, and not in "Unlinked" state.

Verification

  1. Right-click the program blocks folder → Compile > Software (rebuild all).
  2. Open Inspector > Compile. The warning list should show 0 entries for the affected block.
  3. Download the project to the S7-300 CPU (or PLCSIM) and perform an online → Compare to confirm block consistency.
  4. Force the affected tag in a watch table and toggle the value. The CPU should accept the write without SF / BF diagnostic LEDs.
  5. Open Online & Diagnostics > Diagnostic buffer and verify no OB121 (programming error) or OB122 (I/O access error) entries appeared during the test cycle.

Edge Cases and Field Caveats

Multi-instance FBs. Inside a multi-instance FB, the compiler reserves static memory in the parent instance DB. Absolute L-stack addressing inside such a block almost always indicates a bug — the developer likely intended a Static member. Replace with #Instance.MyVar where MyVar is declared under Static.

Library blocks compiled against a different firmware. If a library FC was compiled on TIA V15 and is being used in a V13 project, the warning may be persistent in V13 even though V15 suppresses it. Compile the library from source in V13 to regenerate the block with a V13-compatible symbol table.

Know-how-protected blocks. If you cannot edit the block interface, the message filter is the only static option. Alternatively, replace the protected block with a copy whose interface you can edit.

Optimized vs. standard block access. The S7-300/400 platform uses standard access only. There is no optimized bit/byte/word overlay in the same sense as S7-1200/1500, so the AT construct is the sole method to project a typed view onto the same memory.

Local data size overflow. If the S7-300 CPU is configured with a local data size smaller than the temp footprint of a deeply nested call chain, the CPU will enter STOP with OB121 (length error when reading/writing local data). The compiler warning is the pre-emptive indicator — address it before deployment, not after the first STOP.

Troubleshooting Matrix

Symptom Likely Cause Fix
Warning persists after adding a Temp row Block was not recompiled (incremental compile) Right-click block → Compile → Software (rebuild all)
Warning reappears after every project save Auto-generated code from a library or HMI tag is using L-stack Open the referenced library, restructure per Solution 4
Warning only on FB, not FC Compiler treats Static differently from Temp Move the L-stack operand into the Static section (instance DB-backed)
Warning disappears in V14+ but remains in V13 Compiler rule was relaxed in V14 Upgrade project or accept the warning in V13
IEC check is disabled but warning still shows This rule is not gated by the IEC check flag Use Solution 1 or Solution 3
OB121 / OB122 in diagnostic buffer Local data size exceeded or undeclared L-stack overflow Increase Local data size in CPU properties → Cycle

Best Practices Going Forward

  • Author new logic in SCL where possible. The editor blocks absolute L-stack addressing at source level.
  • For STL blocks, set the project option "Warn when address is not occupied by a tag" to Error via the project properties if your engineering rules require clean builds.
  • When importing V5.x projects, run the "Migration cleanup" pass that converts absolute temporaries to typed symbols. This is part of the standard TIA migration wizard.
  • Reserve AT overlays for the rare cases where byte-level reinterpretation is genuinely required (e.g. status word packing). Never use them as a substitute for a typed interface.

Can the "address is not occupied by a tag" warning be turned off for a single block in TIA Portal V13?

No. TIA Portal V13 does not expose a per-block or per-message filter for this rule. The only static options are declaring a matching Temp variable (Solution 1) or using the global message filter, which silences every warning of the same category across the project.

Does the AT construct work on S7-300 CPUs in TIA Portal V13?

Yes, but only inside an SCL block and only for locally-scoped overlays. The AT view cannot be exported to the block interface or to OPC, and the underlying variable must reside in the instance DB (Static) or in the L-stack (Temp). See Siemens FAQ 57132240 for the full matrix.

Why does the warning persist even with IEC checks disabled on the block?

The "address is not occupied by a tag" rule is enforced at the compiler core, not the IEC 61131-3 check layer. Toggling IEC checks in the block properties relaxes type-compatibility rules but does not change the operand-to-symbol mapping requirement. The only way to suppress it is a Temp declaration or the global filter.

Is the warning related to an OB121 programming error at runtime?

Not directly. The warning is a compile-time signal that the operand is undeclared; the CPU will still execute the absolute L-stack read/write. However, if the call chain's temp footprint exceeds the CPU's configured local data size, the runtime will enter STOP with OB121, and this warning is the pre-emptive hint that the footprint is too large.

Can migrated STEP 7 V5.x AWL code be cleaned up automatically?

Partially. The TIA migration wizard imports AWL source verbatim and does not generate Temp declarations for raw L-stack references. Use the restructure pattern in Solution 4 to convert each absolute operand to a typed Temp row, then recompile. There is no bulk "auto-declare" tool, so the cleanup is manual but straightforward for blocks with fewer than ~20 L-stack references.

Back to blog