Skip to main content

Fix Terraform Error: Invalid Type Specification

Key Takeaway

Fix terraform invalid type specification errors. Don't quote type names, use correct type constructors, and learn all Terraform variable types including optional attributes.

Table of Contents

Quick Answer

# ❌ Don't quote type names
variable "name" {
  type = "string"     # Wrong — quotes make it a string literal
}

# ✅ Types are keywords, not strings
variable "name" {
  type = string
}

The Error

Error: Invalid type specification

  on variables.tf line 2, in variable "name":
   2:   type = "string"

A type specification is either a primitive type keyword (bool, number,
string) or a complex type constructor call, like list(string).

What Causes This

  1. Quoted type names"string" instead of string
  2. Invalid type constructorarray(string) instead of list(string)
  3. Missing parentheseslist string instead of list(string)
  4. Old Terraform 0.11 syntaxtype = "list" was valid before 0.12

All Valid Types

Primitive Types

variable "name"    { type = string }   # "hello"
variable "count"   { type = number }   # 42, 3.14
variable "enabled" { type = bool }     # true, false

Collection Types

variable "names" { type = list(string) }
# ["web", "api", "db"]

variable "ports" { type = list(number) }
# [80, 443, 8080]

variable "tags" { type = map(string) }
# { Environment = "prod", Team = "platform" }

variable "unique_ids" { type = set(string) }
# ["a", "b", "c"] — duplicates removed

Structural Types

# Object — fixed keys with types
variable "database" {
  type = object({
    engine         = string
    instance_class = string
    port           = number
    multi_az       = bool
  })
}

# Tuple — fixed-length list with typed positions
variable "config" {
  type = tuple([string, number, bool])
  # ["web", 8080, true]
}

Nested Types

variable "ingress_rules" {
  type = list(object({
    port        = number
    protocol    = string
    cidr_blocks = list(string)
  }))
}

variable "environment_tags" {
  type = map(map(string))
  # { prod = { owner = "ops" }, dev = { owner = "dev" } }
}

Optional Attributes (Terraform 1.3+)

variable "instance" {
  type = object({
    name          = string
    instance_type = string
    monitoring    = optional(bool, false)       # Default: false
    tags          = optional(map(string), {})   # Default: {}
    ebs_size      = optional(number)            # Default: null
  })
}

Any Type

variable "flexible" {
  type = any    # Accepts anything — use sparingly
}

variable "mixed_list" {
  type = list(any)    # List of anything
}

Common Mistakes

WrongCorrectWhy
type = "string"type = stringDon’t quote keywords
type = "list"type = list(string)Old TF 0.11 syntax
type = array(string)type = list(string)No array type in HCL
type = hash(string)type = map(string)No hash type
type = dict(string)type = map(string)No dict type
type = inttype = numberNo int — use number
type = floattype = numberNo float — use number
type = booleantype = boolIt’s bool, not boolean

Hands-On Courses

Conclusion

Type specifications are keywords (string, number, bool) or constructors (list(string), map(number), object({...})), never quoted strings. If upgrading from Terraform 0.11, replace type = "list" with type = list(string). Use optional() for object attributes with defaults.

🚀

Level Up Your Terraform Skills

Hands-on courses, books, and resources from Luca Berton

Luca Berton
Written by

Luca Berton

DevOps Engineer, AWS Partner, Terraform expert, and author. Creator of Ansible Pilot, Terraform Pilot, and CopyPasteLearn.