Custom provider throws error if no 'provider' configuration block

We’re creating a provider for an application we have called ‘hyperion’. The provider has 2 configuration options that are optional as they have defaults. here’s the schema:

func (p *hyperionProvider) Schema(_ context.Context, _ provider.SchemaRequest, response *provider.SchemaResponse) {
	response.Schema = schema.Schema{
		Attributes: map[string]schema.Attribute{
			"host": schema.StringAttribute{
				Optional: true,
			},
			"bypass_auth": schema.BoolAttribute{
				Optional: true,
			},
		},
	}
}

If I try and run a ‘plan’ WITHOUT a provider "hyperion" {} block I get:

╷
│ Error: Invalid provider configuration
│ 
│ Provider "<provider path>" requires explicit configuration. Add a provider block to the root module and configure the provider's required arguments as described in the provider documentation.
│ 
╵

I can get it to work if I put the following in my terraform code:

provider "hyperion" {}

But according to the documentation, I shouldn’t have to do that:

Unlike many other objects in the Terraform language, a provider block may be omitted if its contents would otherwise be empty. Terraform assumes an empty default configuration for any provider that is not explicitly configured.

From: Provider Configuration - Configuration Language | Terraform | HashiCorp Developer

Hey there @mike.glenney :wave:!

I wasn’t able to reproduce the error you’re describing with that schema, but your understanding (and the documentation) is correct, you shouldn’t need to add an empty provider block for that to work.

I’m wondering if this error message is a red-herring for a different error, I do see in the Terraform core codebase that this error (stored in a constant here) is returned in a couple other places if it encounters diagnostics, in particular, ValidateProviderConfig and ConfigureProvider.

The two likely places that error could be produced in your provider is in a ValidateConfig implementation or the Configure method, so I’d start by checking that part of your provider. I’m able to produce that “explicit configuration” message by returning an error during Configure

func (p *sandboxProvider) Schema(ctx context.Context, req provider.SchemaRequest, resp *provider.SchemaResponse) {
	resp.Schema = schema.Schema{
		Attributes: map[string]schema.Attribute{
			"host": schema.StringAttribute{
				Optional: true,
			},
			"bypass_auth": schema.BoolAttribute{
				Optional: true,
			},
		},
	}
}

func (p *sandboxProvider) Configure(ctx context.Context, req provider.ConfigureRequest, resp *provider.ConfigureResponse) {
	resp.Diagnostics.Append(diag.NewErrorDiagnostic("test error", "it broke"))
}
terraform {
  required_providers {
    examplecloud = {
      source = "austinvalle/sandbox"
    }
  }
}

resource "examplecloud_thing" "test" {
  attr_1 = "hello"
  attr_3 = 12345
  attr_5 = "world"
}
 $ terraform plan

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: Invalid provider configuration
│ 
│ Provider "registry.terraform.io/austinvalle/sandbox" requires explicit configuration. Add a provider block to the root module
│ and configure the provider's required arguments as described in the provider documentation.
│ 
╵
╷
│ Error: test error
│ 
│   with provider["registry.terraform.io/austinvalle/sandbox"],
│   on <empty> line 0:
│   (source code not available)
│ 
│ it broke

Thank you for taking the time to look into this and for the reply.

You were right. I was creating an API client during Configure which was throwing a Fatal error log. Warning message is a red herring for sure. I was seeing the fatal in the logs but wasn’t correlating it because I was taking the provider error message literally.

The other issue is the behavior when I put in an empty provider config block. The other error I am getting back is this one:

╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ConfigureProvider call. The plugin logs may contain more details.
╵

This error I was attributing to the Fatal. If I set the empty object, I ONLY get this error. If I don’t, I get back this errror AND the explicit config error :man_shrugging: