Did you ever have the DeploymentNotFound
error when using Azure Bicep without any syntax errors? I had the same problem. In this blog post, I will tell you more about the DeploymentNotFound
error, its causes, and how to fix it.
Example Bicep template
To demonstrate and simulate the DeploymentNotFound error, I created a Bicep file with three modules: Module A, B, and C:
- ModuleA is a module without a dependency
- ModuleB has a dependency with ModuleA and is deployed conditionally
- ModuleC has a dependency with ModuleB

Figure 1. Schema of Bicep modules with dependencies
Figure 1 translates to this Bicep code output:
param parDeployModuleB bool = false | |
module moduleA 'ModuleA.Bicep' = { | |
name: 'deploy-module-a' | |
} | |
module moduleB 'ModuleB.bicep' = if (parDeployModuleB) { | |
name: 'deploy-module-b-${uniqueString(moduleA.name)}' | |
params: { | |
parUseModuleAOutputs: moduleA.outputs.outModuleA | |
} | |
} | |
module moduleC 'ModuleC.bicep' = { | |
name: 'deploy-module-c-${uniqueString(moduleB.name)}' | |
params: { | |
parUseModuleBOutputs: moduleB.outputs.outModuleB | |
} | |
} |
This Bicep snippet will fail during deployment, although it is syntactically correct. In the code, you can see that ModuleC has an implicit dependency with ModuleB
. At first glance, this may not appear to be an issue however, you should have to take into account that ModuleB
is conditionally deployed. This means that if parDeployModuleB
is set to false the deployment ModuleB
will never exist. This will cause issues with the deployment of ModuleC
because it’s referencing the deployment name that ModuleB
generates. Deploying the code from figure 1 will result in the DeploymentNotFound
error:
{ | |
"status": "Failed", | |
"error": { | |
"code": "DeploymentFailed", | |
"message": "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.", | |
"details": [ | |
{ | |
"code": "NotFound", | |
"message": "{\r\n \"error\": {\r\n \"code\": \"DeploymentNotFound\",\r\n \"message\": \"Deployment 'deploy-module-b-uzxmwqy25sh6u' could not be found.\"\r\n }\r\n}" | |
} | |
] | |
} | |
} |
DeploymentNotFound error explained
Before diving into details about the DeploymentNotFound
error it is good to understand how the Azure Resource Manager works. The resource manager does not deploy the Bicep file. Before the resource manager starts with the deployment, the Bicep file is transpiled to JSON. During transpiling the resource manager transforms code that is written in language A to language B so that Azure can use it in the backend. To transpile a Bicep file on your own computer run the az bicep build
command, which requires the Azure CLI tooling.
I transpiled the Bicep snippet of figure 1 to JSON. Because of the length of the JSON file (134 lines of code) I have uploaded it on my GitHub Gists. To explain the origin of the error I want to zoom in on a particular section of the JSON file: the parameter usage of module output of ModuleB
used in ModuleC
:
JSON
"parameters": { | |
"parUseModuleBOutputs": { | |
"value": "[reference(resourceId('Microsoft.Resources/deployments', format('deploy-module-b-{0}', uniqueString('deploy-module-a'))), '2020-10-01').outputs.outModuleB.value]" | |
} | |
}, |
Bicep
module moduleC 'ModuleC.bicep' = { | |
name: 'deploy-module-c-${uniqueString(modB.name)}' | |
params: { | |
parUseModuleBOutputs: modB.outputs.outModuleB | |
} | |
} |
In the snippets above the Bicep and JSON variants of dependencies to resources are shown. These snippets are from ModuleC
in which they have a dependency to ModuleB
. The JSON snippet shows the usage of the reference()
function. This function allows to retrieve a runtime state of a resource. In this case, the function tries to refer to Microsoft.Resource/deployments
with the deployment name of ModuleB
. In Bicep this function is abstracted and implicitly written by using the symbolic name of a module or resource: moduleB.outputs.outModuleB
.
During the deployment of ModuleC
the reference()
function causes the DeploymentNotFound
error. The function tries to retrieve the state of ModuleB
and cannot find it due to the false condition for the deployment of ModuleB
. This condition prevents the Azure Resource Manager from finding the necessary deployment information.
DeploymentNotFound fix
To fix the error there are two ways:
- Either make sure to always deploy
ModuleB
, so that the reference to the deployment always exists;
- Or add a ternary expression (shorthand if) to the
parUseModuleBOutputs
inModuleC
like this:
module moduleC 'ModuleC.bicep' = { | |
name: 'deploy-module-c-${uniqueString(moduleB.name)}' | |
params: { | |
parUseModuleBOutputs: parDeployModuleB ? moduleB.outputs.outModuleB : '' | |
} | |
} |
By adding a ternary expression (condition ? true : false) the Azure Resource Manager checks in runtime if the parameter parDeployModuleB
is either true or false. If the parameter is false, the empty string ’’
is used instead of the reference()
method when the parameter is true.
Condition on the module
module moduleC 'ModuleC.bicep' = if (parDeployModuleB) { | |
name: 'deploy-module-c-${uniqueString(moduleB.name)}' | |
params: { | |
parUseModuleBOutputs: moduleB.outputs.outModuleB | |
} | |
} |
Adding a condition on the module ModuleC
won’t suffice. The reason for this is that the resource manager still validates the reference to ModuleB
.
Conclusion
In the examples above I demonstrated how to fix the DeploymentNotFound
error. As you can see Bicep has a lot of abstracted code. It can be unclear what to do when the Bicep is syntactically correct, but the deployment output is an error. When Bicep errors like these are unclear, always check the transpiled version of your Bicep this may uncover more information on why a deployment fails.