hashicorp/terraform · error

cannot serialize updated credentials file: %s

Error message

cannot serialize updated credentials file: %s

What it means

Emitted by `updateLocalHostCredentials` (credentials.go:386) when `json.MarshalIndent(raw, "", " ")` fails while serializing the updated credentials structure. `MarshalIndent` rarely fails because the input is a `map[string]interface{}` already decoded from JSON, so this guards against exotic cases like NaN/Inf numbers that slipped into the map or cyclic references from a corrupted in-memory structure.

Source

Thrown at internal/command/cliconfig/credentials.go:386

			delete(rawCredsMap, givenHost)
		}
	}

	// If we have a new object to store we'll write it in now. If the previous
	// object had the hostname written in a different way then this will
	// appear to change it into our canonical display form, with all the
	// letters in lowercase and other transforms from the Internationalized
	// Domain Names specification.
	if new != nil {
		toStore := new.ToStore()
		rawCredsMap[host.ForDisplay()] = ctyjson.SimpleJSONValue{
			Value: toStore,
		}
	}

	newSrc, err := json.MarshalIndent(raw, "", "  ")
	if err != nil {
		return fmt.Errorf("cannot serialize updated credentials file: %s", err)
	}

	// Now we'll write our new content over the top of the existing file.
	// Because we updated the data structure surgically here we should not
	// have disturbed the meaning of any other content in the file, but it
	// might have a different JSON layout than before.
	// We'll create a new file with a different name first and then rename
	// it over the old file in order to make the change as atomically as
	// the underlying OS/filesystem will allow.
	{
		dir, file := filepath.Split(filename)
		f, err := ioutil.TempFile(dir, file)
		if err != nil {
			return fmt.Errorf("cannot create temporary file to update credentials: %s", err)
		}
		tmpName := f.Name()
		moved := false
		defer func(f *os.File, name string) {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Back up and remove `credentials.tfrc.json`, then re-run `terraform login` to regenerate it cleanly.
  2. Inspect the file for malformed numeric values (e.g. `NaN`, `Infinity`, numbers in quotes mixed with `UseNumber`).
  3. Report a bug if it reproduces on an unmodified file — MarshalIndent failing indicates a Terraform defect.

Example fix

# before
terraform login
# cannot serialize updated credentials file: json: ...

# after (regenerate cleanly)
mv ~/.terraform.d/credentials.tfrc.json ~/.terraform.d/credentials.tfrc.json.bak
terraform login
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check the file round-trips through json.Marshal before Terraform writes.
func credsFileMarshallable(path string) error {
    b, err := os.ReadFile(path)
    if err != nil { return nil }
    var v map[string]interface{}
    dec := json.NewDecoder(bytes.NewReader(b))
    dec.UseNumber()
    if err := dec.Decode(&v); err != nil { return nil }
    if _, err := json.MarshalIndent(v, "", "  "); err != nil {
        return fmt.Errorf("credentials file not serializable: %w", err)
    }
    return nil
}

Try / catch

// if err := src.StoreForHost(host, creds); err != nil {
//     if strings.Contains(err.Error(), "cannot serialize updated credentials file") {
//         // regenerate the file from scratch via 'terraform login'
//     }
// }

Prevention

When it happens

Trigger: Storing/forgetting credentials when the in-memory `raw` map contains a value `json.Marshal` cannot encode — most plausibly a `json.Number` wrapping a non-numeric string, or a manually-injected unsupported type. In normal Terraform operation this is effectively unreachable.

Common situations: Corrupted credentials file with a numeric field that is actually non-numeric after partial edits; third-party tooling that mutated the file into an unmarshallable state. End users almost never trigger this directly.

Related errors


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