Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Infrastructure as Code By James Joyner IV · · 8 min read

Bicep Error: 'BCP037: The property "foo" is not allowed on objects of type' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix Bicep 'Error BCP037: The property "foo" is not allowed on objects of type ...' from misspelled properties, wrong nesting, or api-version drift.

  • #iac
  • #infrastructure-as-code
  • #bicep
  • #troubleshooting
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

BCP037 is a compile-time warning-or-error meaning you set a property that the type definition for that object does not recognize. Bicep validates your resource bodies against the type schema for the resource’s @api-version. When you add a property that is not part of that schema — because it is misspelled, nested at the wrong level, or does not exist in the API version you pinned — Bicep flags it and lists the properties it does accept.

The message reads:

main.bicep(18,5) : Error BCP037: The property "foo" is not allowed on objects of type "StorageAccountPropertiesCreateParameters". Permissible properties include "accessTier", "allowBlobPublicAccess", "encryption", "minimumTlsVersion", "networkAcls", "supportsHttpsTrafficOnly". [https://aka.ms/bicep/core-diagnostics#BCP037]

The “Permissible properties include …” list is the most useful part — it tells you exactly what the type expects, so the correct property name is usually right there. Note that BCP037 is often emitted as a warning rather than a hard error for top-level resource properties (Bicep tolerates unknown properties in some cases so templates can pass through newer API features), but for strongly-typed nested objects it is a build-breaking error. Treat it as a real problem either way.

Symptoms

  • az bicep build reports Error BCP037 (or a yellow squiggle warning in VS Code) naming a property and a type.
  • The message enumerates “Permissible properties include …” — the valid set for that object.
  • A property that is valid in the Azure docs is rejected — because the docs describe a newer API version than the one you pinned.
  • A property works at one nesting level but is rejected at another (e.g. placed on the resource instead of under properties).
  • Deployment never starts (hard error) or deploys but silently drops your intended setting (warning).

Common Root Causes

1. Misspelled or wrong-case property name

accesTier instead of accessTier, enableHttpsTrafficOnly instead of supportsHttpsTrafficOnly. Bicep property names are case-sensitive.

resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: 'examplestor'
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
  properties: {
    acccessTier: 'Hot'   // BCP037 — typo, should be accessTier
  }
}

2. Property nested at the wrong level

Many settings belong under properties: { ... }, not directly on the resource — or vice versa. Putting accessTier at the top level instead of inside properties triggers BCP037 against the resource type.

resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: 'examplestor'
  location: location
  accessTier: 'Hot'   // BCP037 — belongs under `properties`, not here
}

3. API-version drift

You pinned an older @api-version that predates the property. The Azure docs (and your memory) reflect a newer version where the property exists. The schema Bicep validates against is the one in your @api-version string.

// minimumTlsVersion was not in very old API versions:
resource sa 'Microsoft.Storage/storageAccounts@2019-04-01' = {
  // ...
  properties: {
    minimumTlsVersion: 'TLS1_2'   // BCP037 on an old api-version
  }
}

4. Property belongs to a different resource type

Copy-pasting from another resource’s example — e.g. putting a Key Vault property on a Storage Account object.

5. Using a discriminated-union property for the wrong kind

Some resource types change their allowed properties based on kind or sku. A property valid for one variant is rejected for another.

How to Diagnose

Step 1: Read the “Permissible properties” list

az bicep build --file main.bicep

Compare the property you wrote against the enumerated list in the error. A near-match (off by a letter or case) means a typo; a total absence means wrong nesting, wrong type, or wrong api-version.

Step 2: Check the API version you pinned versus what’s available

List the API versions the provider actually supports:

az provider show --namespace Microsoft.Storage \
  --query "resourceTypes[?resourceType=='storageAccounts'].apiVersions[]" \
  --output table

If a much newer version exists than the one in your template, drift is the likely cause.

Step 3: Confirm the correct schema

Let the Bicep language server autocomplete the property. In VS Code, delete the property value and press Ctrl+Space inside the object — only valid properties for that type and api-version are offered. If your property is not listed, it does not belong there.

Step 4: Verify nesting against a known-good example

Compare your resource body to the export of a real, deployed resource:

az resource show --ids /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg/providers/Microsoft.Storage/storageAccounts/examplestor \
  --query properties

Fixes

Correct the spelling / casing

Match the exact property name from the “Permissible properties” list:

properties: {
  accessTier: 'Hot'
  minimumTlsVersion: 'TLS1_2'
  supportsHttpsTrafficOnly: true
}

Move the property to the right nesting level

Most configuration lives under properties; name, location, sku, kind, and tags live at the top level:

resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: 'examplestor'
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
  properties: {
    accessTier: 'Hot'
  }
}

Bump the API version

Pin a version that actually contains the property, then rebuild:

resource sa 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  // ...
  properties: { minimumTlsVersion: 'TLS1_2' }
}
az bicep build --file main.bicep && echo "compiles clean"

Remove properties that belong to another type

Delete the pasted-in property and set it on the correct resource instead.

What to Watch Out For

  • The “Permissible properties include …” list is your answer key — read it before guessing.
  • Azure docs describe the latest API version; always cross-check against the @api-version you actually pinned.
  • Keep @api-version current but pinned — never floating — so property availability is predictable and reviewable.
  • Property names are case-sensitive; rely on IntelliSense rather than typing from memory.
  • BCP037 sometimes emits as a warning for top-level properties; do not ignore the yellow squiggles — a “warning” here means your setting is being dropped.
  • When a resource’s valid properties depend on kind/sku, set those first so the language server offers the right schema.
Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.