hashicorp/terraform · error

missing provider schema

Error message

missing provider schema

What it means

Thrown by the plugin protocol v6 gRPC client in GetProviderSchema after a successful GetProviderSchema RPC that returned no diagnostics but whose response carried a nil Provider schema block. It signals that the provider plugin on the other end of the gRPC channel replied with a well-formed message that is nonetheless missing the mandatory top-level provider schema, so Terraform cannot reason about the provider's configuration. This is a provider-implementation contract violation rather than a network or user-config problem.

Source

Thrown at internal/plugin6/grpc_provider.go:146

	// Note: this option is marked as EXPERIMENTAL in the grpc API. We keep
	// this for compatibility, but recent providers all set the max message
	// size much higher on the server side, which is the supported method for
	// determining payload size.
	const maxRecvSize = 64 << 20
	protoResp, err := p.client.GetProviderSchema(p.ctx, new(proto6.GetProviderSchema_Request), grpc.MaxRecvMsgSizeCallOption{MaxRecvMsgSize: maxRecvSize})
	if err != nil {
		resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
		return resp
	}

	resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))

	if resp.Diagnostics.HasErrors() {
		return resp
	}

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

	identResp, err := p.client.GetResourceIdentitySchemas(p.ctx, new(proto6.GetResourceIdentitySchemas_Request))
	if err != nil {
		if status.Code(err) == codes.Unimplemented {
			// We don't treat this as an error if older providers don't implement this method,
			// so we create an empty map for identity schemas
			identResp = &proto6.GetResourceIdentitySchemas_Response{
				IdentitySchemas: map[string]*proto6.ResourceIdentitySchema{},
			}
		} else {
			resp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))
			return resp
		}
	}

	resp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(identResp.Diagnostics))

View on GitHub (pinned to c9def3e214)

Solutions

  1. Verify the provider is a real, current release: run `terraform providers` and `terraform init -upgrade` to pull the latest compatible version.
  2. Confirm the provider binary matches this Terraform version's plugin protocol; check the provider's CHANGELOG/compatibility matrix and pin a known-good version in required_providers.
  3. If the provider is custom/in-house, inspect its GetProviderSchema handler and ensure it always returns a non-nil Provider schema (resp.Provider = ...) in the gRPC response.
  4. Reproduce with TF_LOG=TRACE to capture the provider handshake; a crash or early exit of the provider subprocess usually precedes this error.
  5. File an issue against the provider with the log output if it happens with an official provider release.

Example fix

// provider (terraform-plugin-framework) handler returning the schema
// before
func (p) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
    // resp.Schema left zero -> triggers 'missing provider schema'
}
// after
func (p) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "token": schema.StringAttribute{Optional: true},
        },
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// After calling providers.Interface.GetProviderSchema, always inspect diagnostics.
resp := p.GetProviderSchema()
if resp.Diagnostics.HasErrors() {
    // 'missing provider schema' lands here; fail fast with context.
    return fmt.Errorf("provider %s returned no usable schema: %w", addr, resp.Diagnostics.Err())
}
if resp.Provider.Block == nil {
    return errors.New("provider schema present but empty")
}

Type guard

// Sentinel has no var; detect by message via the diagnostics string.
func isMissingProviderSchema(d tfdiags.Diagnostics) bool {
    return d.Err() != nil && strings.Contains(d.Err().Error(), "missing provider schema")
}

Try / catch

if resp.Diagnostics.HasErrors() {
    if isMissingProviderSchema(resp.Diagnostics) {
        // prompt provider upgrade / re-init rather than retry blindly
        return fmt.Errorf("provider %s returned no schema; run 'terraform init -upgrade' or verify provider compatibility", addr)
    }
    return resp.Diagnostics.Err()
}

Prevention

When it happens

Trigger: Reached exactly at internal/plugin6/grpc_provider.go:146 when the proto6 GetProviderSchema_Response.Provider field is nil following a successful call with no error diagnostics. The same check exists for plugin v5 in internal/plugin/grpc_provider.go:134. It fires whenever a provider process returns an empty/zero provider schema object.

Common situations: Running a broken, stub, mock, or half-implemented provider (e.g. a test harness or a provider built against an outdated SDK that omits the provider block). A version skew between the provider binary and the plugin protocol Terraform expects. A provider that crashed mid-handshake but whose gRPC stream still returned a partial response. A custom/in-house provider that never populated resp.Provider in its schema handler.

Related errors


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