hashicorp/terraform · error

missing provisioner schema

Error message

missing provisioner schema

What it means

Thrown in GRPCProvisioner.GetSchema when the provisioner's GetProvisionerSchema gRPC response succeeds but protoResp.Provisioner is nil. The provisioner plugin returned a schema response with no top-level provisioner block, which Terraform treats as a defect.

Source

Thrown at internal/plugin/grpc_provisioner.go:72

func (p *GRPCProvisioner) GetSchema() (resp provisioners.GetSchemaResponse) {
	p.mu.Lock()
	defer p.mu.Unlock()

	if p.schema != nil {
		return provisioners.GetSchemaResponse{
			Provisioner: p.schema,
		}
	}

	protoResp, err := p.client.GetSchema(p.ctx, new(proto.GetProvisionerSchema_Request))
	if err != nil {
		resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
		return resp
	}
	resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))

	if protoResp.Provisioner == nil {
		resp.Diagnostics = resp.Diagnostics.Append(errors.New("missing provisioner schema"))
		return resp
	}

	resp.Provisioner = convert.ProtoToConfigSchema(protoResp.Provisioner.Block)

	p.schema = resp.Provisioner

	return resp
}

func (p *GRPCProvisioner) ValidateProvisionerConfig(r provisioners.ValidateProvisionerConfigRequest) (resp provisioners.ValidateProvisionerConfigResponse) {
	schema := p.GetSchema()
	if schema.Diagnostics.HasErrors() {
		resp.Diagnostics = resp.Diagnostics.Append(schema.Diagnostics)
		return resp
	}

	mp, err := msgpack.Marshal(r.Config, schema.Provisioner.ImpliedType())

View on GitHub (pinned to c9def3e214)

Solutions

  1. Upgrade or rebuild the provisioner so GetProvisionerSchema returns a non-nil provisioner block.
  2. Ensure the provisioner SDK version matches the Terraform plugin protocol version.
  3. For custom provisioners, populate the Provisioner schema field in the response.
  4. Clear the plugin cache and reinstall the provisioner binary cleanly.

Example fix

# Custom provisioner (terraform-plugin-sdk) must return a schema:
# before: returned an empty Resource
func (p *Provisioner) GetSchema() (*rpc.GetSchemaResponse, error) {
    return &rpc.GetSchemaResponse{}, nil   # Provisioner nil -> error
}
# after:
func (p *Provisioner) GetSchema() (*rpc.GetSchemaResponse, error) {
    return &rpc.GetSchemaResponse{
        Provisioner: &rpc.Schema{Block: schemaToProto(mySchema)},
    }, nil
}
Defensive patterns

Strategy: validation

Validate before calling

# use only provisioners known to ship a provisioner schema; gate in CI
check "provisioner" {
  assert {
    condition     = contains(["remote-exec","local-exec","file"], var.provisioner_type)
    error_message = "unknown/unsupported provisioner; ensure it returns a schema"
  }
}

Try / catch

# wrap provisioners so a schema failure is caught early in a sandbox
# resource block: provisioner "local-exec" { ... } validated in a scratch apply

Prevention

When it happens

Trigger: A provisioner plugin (custom or in development) whose GetProvisionerSchema omits the Provisioner field; a provisioner built against an incompatible plugin SDK version; a stub returning an empty response.

Common situations: Writing/testing a custom provisioner without fully implementing GetProvisionerSchema; protocol skew; corrupted/half-built provisioner binary.

Related errors


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