Bicep Error: 'BCP037: The property "foo" is not allowed on objects of type' — Cause, Fix, and Troubleshooting Guide
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
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 buildreportsError 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-versionyou actually pinned. - Keep
@api-versioncurrent 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.
Related Guides
- Bicep InvalidTemplate & BCP Compile Errors
- Bicep BCP057: Name Does Not Exist in the Current Context
- Detecting and Fixing Infrastructure Config Drift
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.