Skip to content

Wrong detailed exit code when using the refresh only option #37406

@boussarsar

Description

@boussarsar

Terraform Version

Terraform v1.12.2

Terraform Configuration Files

resource "aws_ebs_volume" "example" {
  availability_zone = "us-east-1c"
  size              = 40

  tags = {
    Name = "Pipeline PoC"
  }
}

terraform {
  backend "s3" {
    bucket = "..."
    key    = "pipeline-poc"
    region = "us-east-1"
    profile = "..."
  }
}

provider "aws" {
 region = "us-east-1"
 profile = "..."
}

Debug Output

aws_ebs_volume.example: Refreshing state... [id=vol-09f9d4c4286366762]
2025-08-06T12:31:48.838+0200 [TRACE] GRPCProvider: ReadResource
2025-08-06T12:31:48.838+0200 [TRACE] GRPCProvider: GetProviderSchema
2025-08-06T12:31:48.838+0200 [TRACE] GRPCProvider: returning cached schema: EXTRA_VALUE_AT_END=registry.terraform.io/hashicorp/aws
2025-08-06T12:31:48.838+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: Received request: tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 tf_resource_type=aws_ebs_volume tf_rpc=ReadResource @caller=github.com/hashicorp/terraform-plugin-go@v0.28.0/tfprotov5/tf5server/server.go:847 @module=sdk.proto tf_proto_version=5.9 tf_provider_addr=registry.terraform.io/hashicorp/aws timestamp="2025-08-06T12:31:48.838+0200"
2025-08-06T12:31:48.838+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: Announced client capabilities: @caller=github.com/hashicorp/terraform-plugin-go@v0.28.0/tfprotov5/internal/tf5serverlogging/client_capabilities.go:66 @module=sdk.proto tf_client_capability_deferral_allowed=false tf_resource_type=aws_ebs_volume tf_proto_version=5.9 tf_provider_addr=registry.terraform.io/hashicorp/aws tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 tf_rpc=ReadResource timestamp="2025-08-06T12:31:48.838+0200"
2025-08-06T12:31:48.838+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: Sending request downstream: tf_proto_version=5.9 tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 tf_resource_type=aws_ebs_volume tf_rpc=ReadResource @module=sdk.proto @caller=github.com/hashicorp/terraform-plugin-go@v0.28.0/tfprotov5/internal/tf5serverlogging/downstream_request.go:22 tf_provider_addr=registry.terraform.io/hashicorp/aws timestamp="2025-08-06T12:31:48.838+0200"
2025-08-06T12:31:48.838+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: calling downstream server: @caller=github.com/hashicorp/terraform-plugin-mux@v0.20.0/internal/logging/mux.go:19 @module=sdk.mux tf_mux_provider="*schema.GRPCProviderServer" tf_rpc=ReadResource timestamp="2025-08-06T12:31:48.838+0200"
2025-08-06T12:31:48.839+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: Calling downstream: tf_mux_provider="*schema.GRPCProviderServer" tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 tf_rpc=ReadResource @module=sdk.helper_schema tf_resource_type=aws_ebs_volume @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.37.0/helper/schema/resource.go:1161 tf_provider_addr=registry.terraform.io/hashicorp/aws timestamp="2025-08-06T12:31:48.838+0200"
2025-08-06T12:31:48.840+0200 [DEBUG] provider.terraform-provider-aws_v6.7.0_x5: HTTP Request Sent: http.method=POST tf_aws.sdk=aws-sdk-go-v2 @module=aws http.request.header.authorization="AWS4-HMAC-SHA256 Credential=ASIA************VXGS/20250806/us-east-1/ec2/aws4_request, SignedHeaders=amz-sdk-invocation-id;amz-sdk-request;content-length;content-type;host;x-amz-date;x-amz-security-token, Signature=*****" http.url=https://ec2.us-east-1.amazonaws.com/ http.user_agent="APN/1.0 HashiCorp/1.0 Terraform/1.11.0 (+https://www.terraform.io) terraform-provider-aws/6.7.0 (+https://registry.terraform.io/providers/hashicorp/aws) aws-sdk-go-v2/1.37.1 ua/2.1 os/macos lang/go#1.24.5 md/GOOS#darwin md/GOARCH#arm64 api/ec2#1.238.0 m/C,t,u" tf_aws.signing_region="" @caller=github.com/hashicorp/aws-sdk-go-base/v2@v2.0.0-beta.65/logging/tf_logger.go:45 http.request.header.content_type=application/x-www-form-urlencoded http.request.header.x_amz_security_token="*****" http.request.header.amz_sdk_invocation_id=fd94f909-a733-478e-a732-6dc0e05103aa http.request.header.amz_sdk_request="attempt=1; max=25" net.peer.name=ec2.us-east-1.amazonaws.com tf_mux_provider="*schema.GRPCProviderServer" tf_rpc=ReadResource aws.region=us-east-1 http.request_content_length=74 tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 tf_resource_type=aws_ebs_volume rpc.system=aws-api http.request.header.x_amz_date=20250806T103148Z rpc.service=EC2 tf_provider_addr=registry.terraform.io/hashicorp/aws rpc.method=DescribeVolumes
  http.request.body=
  | Action=DescribeVolumes&Version=2016-11-15&VolumeId.1=vol-09f9d4c4286366762
   timestamp="2025-08-06T12:31:48.839+0200"
2025-08-06T12:31:49.376+0200 [DEBUG] provider.terraform-provider-aws_v6.7.0_x5: HTTP Response Received: aws.region=us-east-1 http.status_code=200 tf_resource_type=aws_ebs_volume http.response.header.x_amzn_requestid=8e87ad5b-b987-4102-89cb-bc8ad3a9b098 rpc.method=DescribeVolumes rpc.service=EC2 @caller=github.com/hashicorp/aws-sdk-go-base/v2@v2.0.0-beta.65/logging/tf_logger.go:45 @module=aws http.duration=535
  http.response.body=
  | <?xml version="1.0" encoding="UTF-8"?>
  | <DescribeVolumesResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
  |     <requestId>8e87ad5b-b987-4102-89cb-bc8ad3a9b098</requestId>
  |     <volumeSet>
  |         <item>
  |             <volumeId>vol-09f9d4c4286366762</volumeId>
  |             <size>40</size>
  |             <snapshotId/>
  |             <availabilityZone>us-east-1c</availabilityZone>
  |             <availabilityZoneId>use1-az6</availabilityZoneId>
  |             <status>available</status>
  |             <createTime>2025-08-06T09:40:38.882Z</createTime>
  |             <attachmentSet/>
  |             <tagSet>
  |                 <item>
  |                     <key>Name</key>
  |                     <value>Pipeline PoC</value>
  |                 </item>
  |             </tagSet>
  |             <volumeType>gp2</volumeType>
  |             <iops>120</iops>
  |             <encrypted>true</encrypted>
  |             <kmsKeyId>arn:aws:kms:us-east-1:4:key/5af3d267-9517-4ad7-a265-749f2f302bdf</kmsKeyId>
  |             <multiAttachEnabled>false</multiAttachEnabled>
  |             <operator>
  |                 <managed>false</managed>
  |             </operator>
  |             <volumeArn>arn:aws:ec2:us-east-1:XXX:volume/vol-09f9d4c4286366762</volumeArn>
  |             <ownerId>XX</ownerId>
  |         </item>
  |     </volumeSet>
  | </DescribeVolumesResponse>
   tf_aws.sdk=aws-sdk-go-v2 tf_provider_addr=registry.terraform.io/hashicorp/aws tf_aws.signing_region="" tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 http.response.header.cache_control="no-cache, no-store" http.response.header.strict_transport_security="max-age=31536000; includeSubDomains" http.response_content_length=1312 tf_rpc=ReadResource http.response.header.content_type=text/xml;charset=UTF-8 http.response.header.date="Wed, 06 Aug 2025 10:31:49 GMT" http.response.header.server=AmazonEC2 rpc.system=aws-api tf_mux_provider="*schema.GRPCProviderServer" timestamp="2025-08-06T12:31:49.375+0200"
2025-08-06T12:31:49.379+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: Called downstream: @caller=github.com/hashicorp/terraform-plugin-sdk/v2@v2.37.0/helper/schema/resource.go:1163 @module=sdk.helper_schema tf_provider_addr=registry.terraform.io/hashicorp/aws tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 tf_resource_type=aws_ebs_volume tf_rpc=ReadResource tf_mux_provider="*schema.GRPCProviderServer" timestamp="2025-08-06T12:31:49.376+0200"
2025-08-06T12:31:49.379+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: Received downstream response: @module=sdk.proto diagnostic_error_count=0 diagnostic_warning_count=0 tf_provider_addr=registry.terraform.io/hashicorp/aws @caller=github.com/hashicorp/terraform-plugin-go@v0.28.0/tfprotov5/internal/tf5serverlogging/downstream_request.go:42 tf_proto_version=5.9 tf_req_duration_ms=538 tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 tf_resource_type=aws_ebs_volume tf_rpc=ReadResource timestamp="2025-08-06T12:31:49.377+0200"
2025-08-06T12:31:49.379+0200 [TRACE] provider.terraform-provider-aws_v6.7.0_x5: Served request: tf_resource_type=aws_ebs_volume tf_rpc=ReadResource @caller=github.com/hashicorp/terraform-plugin-go@v0.28.0/tfprotov5/tf5server/server.go:878 @module=sdk.proto tf_proto_version=5.9 tf_provider_addr=registry.terraform.io/hashicorp/aws tf_req_id=97d5f9b5-c9c6-671f-7d45-8d711154bd33 timestamp="2025-08-06T12:31:49.377+0200"
2025-08-06T12:31:49.380+0200 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/aws" is in the global cache
2025-08-06T12:31:49.380+0200 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState to refreshState for aws_ebs_volume.example
2025-08-06T12:31:49.380+0200 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState: writing state object for aws_ebs_volume.example
2025-08-06T12:31:49.380+0200 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/aws" is in the global cache
2025-08-06T12:31:49.380+0200 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState to workingState for aws_ebs_volume.example
2025-08-06T12:31:49.380+0200 [TRACE] NodeAbstractResouceInstance.writeResourceInstanceState: writing state object for aws_ebs_volume.example
2025-08-06T12:31:49.380+0200 [TRACE] vertex "aws_ebs_volume.example": visit complete
2025-08-06T12:31:49.381+0200 [TRACE] vertex "root": starting visit (terraform.graphNodeRoot)
2025-08-06T12:31:49.381+0200 [TRACE] vertex "root": does not belong to any module instance
2025-08-06T12:31:49.381+0200 [TRACE] vertex "root": visit complete
2025-08-06T12:31:49.381+0200 [TRACE] vertex "aws_ebs_volume.example (expand)": dynamic subgraph completed successfully
2025-08-06T12:31:49.381+0200 [TRACE] vertex "aws_ebs_volume.example (expand)": visit complete
2025-08-06T12:31:49.381+0200 [TRACE] vertex "provider[\"registry.terraform.io/hashicorp/aws\"] (close)": starting visit (*terraform.graphNodeCloseProvider)
2025-08-06T12:31:49.381+0200 [TRACE] vertex "provider[\"registry.terraform.io/hashicorp/aws\"] (close)": does not belong to any module instance
2025-08-06T12:31:49.381+0200 [TRACE] GRPCProvider: Close
2025-08-06T12:31:49.382+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2025-08-06T12:31:49.392+0200 [INFO]  provider: plugin process exited: plugin=.terraform/providers/registry.terraform.io/hashicorp/aws/6.7.0/darwin_arm64/terraform-provider-aws_v6.7.0_x5 id=89637
2025-08-06T12:31:49.392+0200 [DEBUG] provider: plugin exited
2025-08-06T12:31:49.392+0200 [TRACE] vertex "provider[\"registry.terraform.io/hashicorp/aws\"] (close)": visit complete
2025-08-06T12:31:49.393+0200 [TRACE] vertex "root": starting visit (*terraform.nodeCloseModule)
2025-08-06T12:31:49.393+0200 [TRACE] vertex "root": does not belong to any module instance
2025-08-06T12:31:49.393+0200 [TRACE] vertex "root": visit complete
2025-08-06T12:31:49.393+0200 [TRACE] LoadSchemas: retrieving schema for provider type "registry.terraform.io/hashicorp/aws"
2025-08-06T12:31:49.393+0200 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/aws" is in the global cache
2025-08-06T12:31:49.393+0200 [TRACE] LoadSchemas: retrieving schema for provider type "registry.terraform.io/hashicorp/aws"
2025-08-06T12:31:49.393+0200 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/aws" is in the global cache
2025-08-06T12:31:49.393+0200 [TRACE] LoadSchemas: retrieving schema for provider type "registry.terraform.io/hashicorp/aws"
2025-08-06T12:31:49.393+0200 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/aws" is in the global cache
2025-08-06T12:31:49.393+0200 [TRACE] Plan is complete
2025-08-06T12:31:49.393+0200 [TRACE] Plan is applyable
2025-08-06T12:31:49.393+0200 [TRACE] LoadSchemas: retrieving schema for provider type "registry.terraform.io/hashicorp/aws"
2025-08-06T12:31:49.393+0200 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/aws" is in the global cache
2025-08-06T12:31:49.393+0200 [DEBUG] no planned changes, skipping apply graph check
2025-08-06T12:31:49.393+0200 [INFO]  backend/local: plan operation completed
2025-08-06T12:31:49.393+0200 [TRACE] LoadSchemas: retrieving schema for provider type "registry.terraform.io/hashicorp/aws"
2025-08-06T12:31:49.393+0200 [TRACE] terraform.contextPlugins: Schema for provider "registry.terraform.io/hashicorp/aws" is in the global cache

No changes. Your infrastructure still matches the configuration.

Terraform has checked that the real remote objects still match the result of your most recent changes, and found no differences.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

fboussarsar@ ebs-example % echo $?
2

Expected Behavior

Using this in a pipeline to detect drift. In AWS CodeBuild (and other similar pipelines), the step fails and exits if a command returns a non-zero code. This is the desired behaviour because we can rely on the return code to fail the "detect drift" step, and alert based on it.

In older versions (I have tried with 1.9), this returned code 0 when no changes are detected, so the command succeeds

-detailed-exitcode Return detailed exit codes when the command exits.
This will change the meaning of exit codes to:
0 - Succeeded, diff is empty (no changes)
1 - Errored
2 - Succeeded, there is a diff

Output from the older version, both with the refresh-only option and without

fboussarsar@ ebs-example % terraform -version                                
Terraform v1.9.0
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v6.7.0

Your version of Terraform is out of date! The latest version
is 1.12.2. You can update by downloading from https://www.terraform.io/downloads.html
fboussarsar@ ebs-example % 
fboussarsar@ ebs-example % 
fboussarsar@ ebs-example % terraform  plan --refresh-only -detailed-exitcode 
aws_ebs_volume.example: Refreshing state... [id=vol-0XXXX]

No changes. Your infrastructure still matches the configuration.

Terraform has checked that the real remote objects still match the result of your most recent changes, and found no differences.
fboussarsar@ ebs-example % echo $?                                           
0
fboussarsar@ ebs-example % terraform  plan  -detailed-exitcode  
aws_ebs_volume.example: Refreshing state... [id=vol-09f9d4c4286366762]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
fboussarsar@ ebs-example % echo $? 
0     

Actual Behavior

Using the "refresh-only" option changes the return code:

terraform  plan --refresh-only -detailed-exitcode  
aws_ebs_volume.example: Refreshing state... [id=vol-09f9d4c4286366762]

No changes. Your infrastructure still matches the configuration.

Terraform has checked that the real remote objects still match the result of your most recent changes, and found no differences.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.


fboussarsar@ ebs-example % echo $?                                           
2
fboussarsar@ ebs-example % 
fboussarsar@ ebs-example % 
fboussarsar@ ebs-example % terraform  plan  -detailed-exitcode  
aws_ebs_volume.example: Refreshing state... [id=vol-09f9d4c4286366762]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

fboussarsar@ ebs-example % echo $?                             
0

Steps to Reproduce

terraform plan -detailed-exitcode
terraform plan --refresh-only -detailed-exitcode

Additional Context

No response

References

No response

Generative AI / LLM assisted development?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugconfirmeda Terraform Core team member has reproduced this issuecore

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions