hashicorp/terraform · error

estimating object is exist got an error: %#v

Error message

estimating object %s is exist got an error: %#v

What it means

Thrown by RemoteClient.getObj in the OSS backend when bucket.IsObjectExist(stateFile) returns an error (not the false 'absent' result). IsObjectExist issues a HEAD-style request; a transport/permission/SDK failure surfaces here before the code can decide whether the state object exists. The %#v dump exposes the SDK error shape.

Solutions

  1. Grant the RAM/STS principal `oss:HeadObject` and `oss:GetObject` on the state key ARN.
  2. Retry `tofu init` - transient network errors to OSS are common and usually clear.
  3. Verify network reachability of the OSS endpoint (VPC endpoints, proxy, DNS).
  4. Confirm c.stateFile path spelling and prefix match the bucket layout.
Defensive patterns

Strategy: retry

Validate before calling

// preflight: principal should have HeadObject on the state key; verify with a HEAD
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// (SDK equivalent: bucket.GetObjectMeta with a short timeout to fail fast)

Try / catch

var lastErr error
for i := 0; i < 3; i++ {
    exist, err := bucket.IsObjectExist(c.stateFile)
    if err == nil {
        break
    }
    lastErr = err
time.Sleep(backoff)
}
if lastErr != nil { return lastErr }

Prevention

When it happens

Trigger: bucket.IsObjectExist(c.stateFile) returns err != nil in the getObj flow. Causes: insufficient RAM/STS permissions for HeadObject on the state key, transient network error to OSS, signature mismatch, or the bucket being deleted between Bucket() and this call.

Common situations: STS token granted Object Read but not HeadObject; VPC endpoint routing broken; state key path prefix wrong so the SDK hits a denied prefix; intermittent DNS failure against the OSS endpoint.

Related errors


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

Appendix: source

Thrown at internal/backend/remote-state/oss/client.go:420

		lockErr.Err = err
		return lockErr
	}

	return nil
}

func (c *RemoteClient) lockPath() string {
	return fmt.Sprintf("%s/%s", c.bucketName, c.stateFile)
}

func (c *RemoteClient) getObj() (*remote.Payload, error) {
	bucket, err := c.ossClient.Bucket(c.bucketName)
	if err != nil {
		return nil, fmt.Errorf("error getting bucket %s: %#v", c.bucketName, err)
	}

	if exist, err := bucket.IsObjectExist(c.stateFile); err != nil {
		return nil, fmt.Errorf("estimating object %s is exist got an error: %#v", c.stateFile, err)
	} else if !exist {
		return nil, nil
	}

	var options []oss.Option
	output, err := bucket.GetObject(c.stateFile, options...)
	if err != nil {
		return nil, fmt.Errorf("error getting object: %#v", err)
	}

	buf := bytes.NewBuffer(nil)
	if _, err := io.Copy(buf, output); err != nil {
		return nil, fmt.Errorf("failed to read remote state: %s", err)
	}
	sum := md5.Sum(buf.Bytes())
	payload := &remote.Payload{
		Data: buf.Bytes(),
		MD5:  sum[:],

View on GitHub (pinned to d32a084675)