hashicorp/terraform · error

Cannot set both 'source' and 'content'

Error message

Cannot set both 'source' and 'content'

What it means

Validation diagnostic from the 'file' provisioner's ValidateProvisionerConfig. The schema declares both 'source' and 'content' as Optional, but they are mutually exclusive; if both are non-null after coercion, this error is emitted and provisioning is aborted.

Source

Thrown at internal/builtin/provisioners/file/resource_provisioner.go:69

			},
		},
	}
	resp.Provisioner = schema
	return resp
}

func (p *provisioner) ValidateProvisionerConfig(req provisioners.ValidateProvisionerConfigRequest) (resp provisioners.ValidateProvisionerConfigResponse) {
	cfg, err := p.GetSchema().Provisioner.CoerceValue(req.Config)
	if err != nil {
		resp.Diagnostics = resp.Diagnostics.Append(err)
	}

	source := cfg.GetAttr("source")
	content := cfg.GetAttr("content")

	switch {
	case !source.IsNull() && !content.IsNull():
		resp.Diagnostics = resp.Diagnostics.Append(errors.New("Cannot set both 'source' and 'content'"))
		return resp
	case source.IsNull() && content.IsNull():
		resp.Diagnostics = resp.Diagnostics.Append(errors.New("Must provide one of 'source' or 'content'"))
		return resp
	}

	return resp
}

func (p *provisioner) ProvisionResource(req provisioners.ProvisionResourceRequest) (resp provisioners.ProvisionResourceResponse) {
	if req.Connection.IsNull() {
		resp.Diagnostics = resp.Diagnostics.Append(tfdiags.WholeContainingBody(
			tfdiags.Error,
			"file provisioner error",
			"Missing connection configuration for provisioner.",
		))
		return resp
	}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Remove either 'source' or 'content' so exactly one is set.
  2. Use 'content' for inline strings, 'source' to copy an existing local file.

Example fix

// before
provisioner "file" {
  source      = "./app.conf"
  content     = "raw config"
  destination = "/etc/app.conf"
}
// after
provisioner "file" {
  content     = "raw config"
  destination = "/etc/app.conf"
}
Defensive patterns

Strategy: validation

Validate before calling

# Validate the provisioner block has exactly one of source/content before apply:
terraform validate
# Or in CI, a custom check (using e.g. tfsh or hclspec) rejecting blocks
# where both source and content are set.

Prevention

When it happens

Trigger: A resource provisioner block sets both 'source = ...' and 'content = ...' at once, e.g. provisioner "file" { source = "./a" content = "x" destination = "/b" }.

Common situations: Copy-pasting a provisioner block and forgetting to delete the old argument; templating that conditionally injects both keys.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/51edd95951ef778b. Report an issue: GitHub.