Question: How do I resolve template validation or template format errors in CloudFormation?

I receive an error message when I try to create my AWS CloudFormation stack.

Short descriptionChoose one of the following solutions based on the error message that you receive:For "JSON not well-formed" or "YAML not well-formed" errors, see the Validate template syntax section.For "Unresolved resource dependencies [XXXXXXXX] in the Resources block of the template" errors, see the Validate logical IDs and parameters section.For "Unrecognized parameter type: XXXXXXXX" or "Invalid template parameter property 'XXXXXXXX'" errors, see the Validate parameter definitions section.For "Every Condition member must be a string" errors, see the Confirm that Conditions is specified as a string section.For "Unrecognized resource types: [XXXXXXXX]" errors, see the Verify the availability of your resource type section.For "The [environmental resource] 'XXXXXXXX' does not exist" errors, see the Verify that your resource exists outside the stack, or validate dependencies for resources in the same stack section.For "Invalid template property or properties [XXXXXXXX]" errors, see the Verify template properties section.

ResolutionNote: If you receive errors when running AWS Command Line Interface (AWS CLI) commands, make sure that you’re using the most recent version of the AWS CLI.Validate template syntaxTo follow proper JSON or YAML syntax in your CloudFormation template, consider the following:Create your stack with AWS CloudFormation Designer.Validate your JSON syntax with a text editor, or a command line tool such as the AWS CLI template validator.Validate your YAML syntax with the aws cloudformation validate-template command.Validate your JSON or YAML templates with the AWS CloudFormation linter on the GitHub website.Validate logical IDs and parametersConfirm that resource logical IDs and parameters are defined in your template.In the following JSON and YAML templates, test is referenced for the ImageId property. However, neither template includes a resource logical ID or parameter named test. These templates return the following error: "Unresolved resource dependencies [test] in the Resources block of the template.” For more information on resource definitions and their syntax, see Resources.Example JSON (incorrect):{  "Resources" : {    "EC2Instance01" : {      "Type" : "AWS::EC2::Instance",      "Properties" : {        "ImageId" : {"Ref": "test"}      }    }  }}Example YAML (incorrect):Resources:  EC2Instance01:    Type: AWS::EC2::Instance    Properties:      ImageId: !Ref testTo resolve this issue, add a resource logical ID that's named test. Or, create a parameter that's named test where the reference returns the imageId value. The following example JSON and YAML templates include a parameter with the name test and imageId as the value.Example JSON (correct):{  "Parameters": {     "test": {         "Type": "String",         "Default": "ami-xxx"       }  },  "Resources" : {    "EC2Instance01" : {      "Type" : "AWS::EC2::Instance",      "Properties" : {        "ImageId" : {"Ref": "test"}      }    }  }}Example YAML (correct):Parameters:  test:    Type: String    Default: ami-xxxResources:  EC2Instance01:    Type: 'AWS::EC2::Instance'    Properties:      ImageId: !Ref testValidate parameter definitions1.    Set Type to one of the following supported properties:String, Number, List , or CommaDelimitedListAWS-specific parameter typesSSM parameter types2.    In your CloudFormation template, verify that the parameters include only the following permitted properties:"Parameters" : {  "ParameterName" : {    "AllowedPattern" : "A regular expression that represents the patterns to allow for String types.",    "AllowedValues" : "An array containing the list of values allowed for the parameter",    "ConstraintDescription" : "A string that explains a constraint when the constraint is violated"    "Default" : "A value of the appropriate type for the template to use if no value is specified when a stack is created. If you define constraints for the parameter, you must specify a value that adheres to those constraints",    "Description" : "A string of up to 4000 characters that describes the parameter",    "MaxLength" : "An integer value that determines the largest number of characters you want to allow for String types",    "MaxValue" : "A numeric value that determines the largest numeric value you want to allow for Number types.",    "MinLength" : "An integer value that determines the smallest number of characters you want to allow for String types.",    "MinValue" : "A numeric value that determines the smallest numeric value you want to allow for Number types.",    "NoEcho" : "Whether to mask the parameter value when a call is made that describes the stack.                 If you set the value to true, the parameter value is masked with asterisks (*****).",    "Type" : "The data type for the parameter (DataType)." },3.    In your CloudFormation template, confirm that the Parameters section doesn't contain any intrinsic functions.In the following example JSON and YAML templates, the default value for ParameterC has the intrinsic function Fn::Sub. This intrinsic function causes the validation error: "Every Default member must be a string."Example JSON (incorrect):{  "Parameters": {    "ParameterA": {      "Type": "String",      "Default": "abc"    },    "ParameterB": {      "Type": "String",      "Default": "def"    },    "ParameterC": {      "Type": "String",      "Default": {        "Fn::Sub": "${ParameterA}-${ParameterB}"      }    }  },  "Resources": {    "MyS3Bucket": {      "Type": "AWS::S3::Bucket",      "Properties": {        "BucketName": {          "Ref": "ParameterC"        }      }    }  }}Example YAML (incorrect):Parameters: ParameterA:  Type: String  Default: abc ParameterB:  Type: String  Default: def ParameterC:  Type: String  Default: !Sub '${ParameterA}-${ParameterB}'Resources: MyS3Bucket:  Type: 'AWS::S3::Bucket'  Properties:   BucketName: !Ref ParameterCConfirm that Conditions is specified as a stringIn your CloudFormation template, specify Conditions as a string.In the following example JSON and YAML templates, the condition in the resource EC2RouteA is specified as a list of strings instead of a single string. These templates result in the following validation error: "Every Condition member must be a string."Example JSON (incorrect):{  "Conditions": {    "ConditionA": {      "Fn::Not": [        {          "Fn::Equals": [            "",            "Sample"          ]        }      ]    },    "ConditionB": {      "Fn::Not": [        {          "Fn::Equals": [            "",            "Sample"          ]        }      ]    }  },  "Resources": {    "EC2RouteA": {      "Type": "AWS::EC2::Route",      "Condition": [        "ConditionA",        "ConditionB"      ],      "Properties": {       ...      }    }  }}Example YAML (incorrect):Conditions: ConditionA: !Not   - !Equals    - ''   - Sample ConditionB: !Not   - !Equals    - ''   - SampleResources:  EC2RouteA:  Type: 'AWS::EC2::Route'  Condition:   - ConditionA   - ConditionB  Properties:To resolve this error, add ConditionAandB to the Conditions section of your template, and then use ConditionAandB as the condition for the EC2RouteA resource. See the following example JSON and YAML templates.Example JSON (correct):{  "Conditions": {    "ConditionA": {      "Fn::Not": [        {          "Fn::Equals": [            "",            "Sample"          ]        }      ]    },    "ConditionB": {      "Fn::Not": [        {          "Fn::Equals": [            "",            "Sample"          ]        }      ]    },    "ConditionAandB": {      "Fn::And": [        {          "Condition": "ConditionA"        },        {          "Condition": "ConditionB"        }      ]    }  },  "Resources": {    "EC2RouteA": {      "Type": "AWS::EC2::Route",      "Condition": "ConditionAandB",      "Properties": {        ...      }    }  }}Example YAML (correct):Conditions:  ConditionA:    Fn::Not:    - Fn::Equals:      - ''      - Sample  ConditionB:    Fn::Not:    - Fn::Equals:      - ''      - Sample  ConditionAandB:    Fn::And:    - Condition: ConditionA    - Condition: ConditionBResources:  EC2RouteA:    Type: AWS::EC2::Route    Condition: ConditionAandB    Properties:Verify the availability of your resource type1.    Verify that your resource is available in your AWS Region.Not all resource types are available in every AWS Region. Templates that include resource types that aren't available in your AWS Region result in the following error: "Unrecognized resource types: [XXXXXXXX]."2.    If your template consists of any serverless resources, then include a Transform declaration. See the following example JSON and YAML templates.Example JSON:{    "Transform": "AWS::Serverless-2016-10-31", #Please make sure to include this.    "Resources": {        "MyServerlessFunctionLogicalID": {            "Type": "AWS::Serverless::Function",            "Properties": {                "Handler": "index.handler",                "Runtime": "nodejs8.10",                "CodeUri": "s3://testBucket/mySourceCode.zip"            }        }   }}Example YAML:Transform: AWS::Serverless-2016-10-31 #Please make sure to include this.Resources:  MyServerlessFunctionLogicalID:    Type: AWS::Serverless::Function    Properties:      Handler: index.handler      Runtime: nodejs8.10      CodeUri: 's3://testBucket/mySourceCode.zip'Verify that your resource exists outside the stack, or validate dependencies for resources in the same stackIf you're hardcoding a resource or Amazon Resource Name (ARN) into one of your stack's resources for one that's outside of the CloudFormation stack, then verify the following:The resource name or ARN is correct.The resource exists.The resource exists in the same AWS Region as the stack. Consider that some resources accept properties across AWS Regions or accounts.For example, an AWS::EC2::Instance resource in your stack that specifies a security group (sg-1234567890) fails if:The security group doesn't exist.The security group doesn't exist in the stack's AWS Region.As a result, you receive the error message: "The sg-1234567890 does not exist." See the following example:LinuxInstance:    Type: AWS::EC2::Instance    Properties:      SubnetId: !Ref ServerSubnetID       KeyName: !Ref EC2KeyPairName      SecurityGroupIds: sg-1234567890 #<This resource must exist and be in the same AWS Region as the stack.>Verify template propertiesUse only permitted template properties in your CloudFormation template.In the following example JSON and YAML templates, the bucket resource is on the same level as the Resources section. This returns the following error: "Template validation error: Invalid template property or properties [Bucket]." This error is caused because the CloudFormation template validator sees the bucket resource as a section-level specification. A section-level specification isn't allowed as a template property.Example JSON (incorrect):{  "Resources": {    "WaitCondition": {      "Type": "AWS::CloudFormation::WaitCondition"    }  },  #<There is an extra '}' causing the Resources section to be closed off after the WaitCondition resource.>  "Bucket": {    "Type": "AWS::S3::Bucket",    "Properties": {      "Name": "BucketName"    }  }}Example YAML (incorrect):Resources:  WaitCondition:    Type: AWS::CloudFormation::WaitConditionBucket: # <The spacing for the entire Bucket resource is incorrect and needs to be shifted 2 spaces to the right.>  Type: AWS::S3::Bucket  Properties:    Name: BucketNameTo resolve this issue, correct the formatting so that the bucket resource is specified inside the Resources section. See the following example JSON and YAML templates that are correctly formatted.Example JSON (correct):{  "Resources": {    "WaitCondition": {      "Type": "AWS::CloudFormation::WaitCondition"    },    "Bucket": {      "Type": "AWS::S3::Bucket",      "Properties": {        "Name": "BucketName"      }    }  }}Example YAML (correct):Resources:  WaitCondition:    Type: 'AWS::CloudFormation::WaitCondition'  Bucket:    Type: 'AWS::S3::Bucket'    Properties:      Name: BucketName