hashicorp/terraform · error · ErrInvalidHostname

invalid hostname

Error message

invalid hostname

What it means

ErrInvalidHostname is returned by cloudplan.LoadSavedPlanBookmark when the loaded JSON plan-bookmark (the tfplan artifact written when a cloud/remote plan is saved) has an empty Hostname field. The bookmark stores the run ID and cloud hostname so a later 'apply' can retrieve the remote plan; a missing hostname means the bookmark is unusable and likely not a real saved-plan bookmark at all. This is a data-integrity guard, not a network error.

Source

Thrown at internal/cloud/cloudplan/saved_plan.go:15

// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1
package cloudplan

import (
	"encoding/json"
	"errors"
	"io"
	"os"
	"strings"
)

var ErrInvalidRemotePlanFormat = errors.New("invalid remote plan format, must be 1")
var ErrInvalidRunID = errors.New("invalid run ID")
var ErrInvalidHostname = errors.New("invalid hostname")

type SavedPlanBookmark struct {
	RemotePlanFormat int    `json:"remote_plan_format"`
	RunID            string `json:"run_id"`
	Hostname         string `json:"hostname"`
}

func NewSavedPlanBookmark(runID, hostname string) SavedPlanBookmark {
	return SavedPlanBookmark{
		RemotePlanFormat: 1,
		RunID:            runID,
		Hostname:         hostname,
	}
}

func LoadSavedPlanBookmark(filepath string) (SavedPlanBookmark, error) {
	bookmark := SavedPlanBookmark{}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Inspect the tfplan/plan file: confirm it has a "hostname" field matching your HCP Terraform / TFE hostname (e.g. app.terraform.io).
  2. Regenerate the plan from scratch with 'terraform plan' against the cloud backend so a fresh, well-formed bookmark is written.
  3. Delete the corrupt bookmark file and re-run 'terraform plan' to recreate it.
  4. If persisting across Terraform versions, ensure both plan and apply run on the same Terraform version that wrote the bookmark.

Example fix

// before: stale tfplan with no hostname key
// {"remote_plan_format":1,"run_id":"run-abc"}
//
// after: regenerate so hostname is populated
// $ terraform plan -out=tfplan    (cloud/remote backend fills hostname)
// $ terraform show -json tfplan   (confirm hostname present)
Defensive patterns

Strategy: validation

Validate before calling

// Before relying on a saved cloud plan bookmark, sanity-check the fields.
func validBookmark(b cloudplan.SavedPlanBookmark) error {
    if b.RemotePlanFormat != 1 {
        return fmt.Errorf("unsupported plan format %d", b.RemotePlanFormat)
    }
    if strings.TrimSpace(b.Hostname) == "" {
        return errors.New("plan bookmark missing hostname; regenerate with 'terraform plan'")
    }
    if !strings.HasPrefix(b.RunID, "run-") {
        return fmt.Errorf("plan bookmark has invalid run ID %q", b.RunID)
    }
    return nil
}

Prevention

When it happens

Trigger: LoadSavedPlanBookmark reads a tfplan file, JSON-unmarshals it into SavedPlanBookmark, and at line 57-58 returns ErrInvalidHostname when bookmark.Hostname == "". Happens when the file exists and parsed as JSON but the "hostname" key is absent, null, or empty.

Common situations: A stale/corrupt tfplan left in the working dir from an aborted cloud run; a tfplan hand-edited or written by an older/incompatible Terraform version; a file that is valid JSON but not a saved-plan bookmark (e.g. a local backend plan json that lacks the remote_plan_format/run_id/hostname keys).

Related errors


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