hashicorp/terraform · critical
missing provider schema
Error message
missing provider schema
What it means
Thrown by the Terraform plugin v5 gRPC client (GRPCProvider.GetProviderSchema) when the provider's GetProviderSchema RPC succeeded and returned no diagnostics, but the `Provider` field of the response is nil. Terraform requires every provider to declare a top-level provider schema block; a nil provider schema means the provider binary is non-conformant or broken. This is a server-side (provider) defect surfaced to the core.
Solutions
- Upgrade the provider to a version compatible with this Terraform core (`terraform providers lock` / `terraform init -upgrade`).
- Clear the plugin cache and re-init: remove .terraform/providers and run terraform init.
- Try the v6 protocol equivalent of the provider, or pin a known-good provider version.
- If you maintain the provider, ensure GetProviderSchema always returns a non-nil Provider block.
Example fix
# before: provider v5 returning empty schema # (provider-side fix; in Go provider code, set resp.Provider in GetProviderSchema) # terraform user-side fix: $ terraform init -upgrade
Defensive patterns
Strategy: retry
Validate before calling
# shell: verify provider responds with a schema before planning $ terraform providers schema -json | jq '.provider_schemas | length'
Try / catch
# bash: init with fallback to upgrade/reinstall on schema failure
if ! terraform init 2>err.log; then
if grep -q 'missing provider schema' err.log; then
rm -rf .terraform/providers && terraform init -upgrade
else
cat err.log; exit 1
fi
fi Prevention
- Pin provider versions in required_providers to known-good releases.
- Run terraform init with -upgrade when a provider starts misbehaving.
- Keep the plugin cache clean; corrupted caches surface as schema errors.
- Run terraform validate in CI after every init.
When it happens
Trigger: A provider plugin's GetProviderSchema handler returned a response with Provider == nil and no error. Typically a mis-built provider, a protocol-version mismatch, or a provider crash that produced an empty response.
Common situations: Using a provider built against an old/new SDK that omits the provider block. A provider binary that crashed mid-handshake. A corrupted provider cache. Version skew between Terraform core and the provider.
Related errors
- action schema not found for action
- identity schema not found for type
- list resource schema not found for type
- list resource schema not found for type
- missing provider schema
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/f2945a80c770096d.
Report an issue: GitHub.
Appendix: source
Thrown at internal/plugin/grpc_provider.go:134
// 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.GetSchema(p.ctx, new(proto.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(proto.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 = &proto.GetResourceIdentitySchemas_Response{
IdentitySchemas: map[string]*proto.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 d32a084675)