{"record":{"id":"f2945a80c770096d","repo":"hashicorp/terraform","slug":"missing-provider-schema","errorCode":null,"errorMessage":"missing provider schema","messagePattern":"missing provider schema","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/plugin/grpc_provider.go","lineNumber":134,"sourceCode":"\t// Note: this option is marked as EXPERIMENTAL in the grpc API. We keep\n\t// this for compatibility, but recent providers all set the max message\n\t// size much higher on the server side, which is the supported method for\n\t// determining payload size.\n\tconst maxRecvSize = 64 << 20\n\tprotoResp, err := p.client.GetSchema(p.ctx, new(proto.GetProviderSchema_Request), grpc.MaxRecvMsgSizeCallOption{MaxRecvMsgSize: maxRecvSize})\n\tif err != nil {\n\t\tresp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))\n\t\treturn resp\n\t}\n\n\tresp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(protoResp.Diagnostics))\n\n\tif resp.Diagnostics.HasErrors() {\n\t\treturn resp\n\t}\n\n\tif protoResp.Provider == nil {\n\t\tresp.Diagnostics = resp.Diagnostics.Append(errors.New(\"missing provider schema\"))\n\t\treturn resp\n\t}\n\n\tidentResp, err := p.client.GetResourceIdentitySchemas(p.ctx, new(proto.GetResourceIdentitySchemas_Request))\n\tif err != nil {\n\t\tif status.Code(err) == codes.Unimplemented {\n\t\t\t// We don't treat this as an error if older providers don't implement this method,\n\t\t\t// so we create an empty map for identity schemas\n\t\t\tidentResp = &proto.GetResourceIdentitySchemas_Response{\n\t\t\t\tIdentitySchemas: map[string]*proto.ResourceIdentitySchema{},\n\t\t\t}\n\t\t} else {\n\t\t\tresp.Diagnostics = resp.Diagnostics.Append(grpcErr(err))\n\t\t\treturn resp\n\t\t}\n\t}\n\n\tresp.Diagnostics = resp.Diagnostics.Append(convert.ProtoToDiagnostics(identResp.Diagnostics))","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/plugin/grpc_provider.go#L116-L152","documentation":"Thrown in GRPCProvider.GetSchema when the provider's GetProviderSchema gRPC response succeeds but protoResp.Provider is nil, i.e. the provider returned a schema response with no top-level provider block. Terraform cannot operate without a provider schema, so it fails.","triggerScenarios":"A provider plugin (often a hand-rolled or in-development one) whose GetProviderSchema implementation omits the Provider field; a provider built against a mismatched plugin SDK/framework version; a stub returning an empty response.","commonSituations":"Authoring/testing a custom provider that hasn't implemented GetProviderSchema fully; protocol-version skew between Terraform and the provider; a corrupted or half-built provider binary.","solutions":["Upgrade the provider to a release that correctly returns its provider schema.","Upgrade Terraform/OpenTofu to a version whose plugin protocol matches the provider.","For custom providers, ensure GetProviderSchema populates the Provider (provider block) schema field.","Rebuild/reinstall the provider plugin cleanly and clear the plugin cache."],"exampleFix":"# For a custom provider (Go, terraform-plugin-framework):\n# before: provider schema field left nil\n# after:\nfunc (p *provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {\n    resp.Schema = provider.Schema{\n        Attributes: map[string]schema.Attribute{\n            \"region\": schema.StringAttribute{Optional: true},\n        },\n    }\n}\n# pin a known-good provider in config:\nrequired_providers { myp = { source = \"acme/myp\", version = \"0.5.0\" } }","handlingStrategy":"validation","validationCode":"# pin a provider known to ship a provider schema and assert compatibility\ncheck \"provider_compat\" {\n  assert {\n    condition     = !contains(data.tfe_outputs.bad.references, \"nil-schema\")\n    error_message = \"provider returned no provider schema; upgrade provider\"\n  }\n}","typeGuard":null,"tryCatchPattern":"# fall back to a pinned version in CI while investigating\n# terraform init -upgrade=false ; with required_providers version = \"=X.Y.Z\"","preventionTips":["Pin provider versions in required_providers and keep the lock file committed.","Test custom providers in isolation before use, asserting GetProviderSchema returns a provider block.","Keep Terraform/OpenTofu and providers on compatible protocol versions.","Reinstall provider binaries cleanly and clear the plugin cache after upgrades."],"tags":["plugin","grpc","provider","schema"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T21:17:07.882Z"}