hashicorp/terraform · error

Can't serialize backend configuration as JSON: %s

Error message

Can't serialize backend configuration as JSON: %s

What it means

In Meta.backend_C_r_s (meta_backend.go:1795), after locking, Terraform calls BackendConfigState.SetConfig(configVal, b.ConfigSchema()) to serialize the decoded backend config value into JSON for storage in the workdir-state file. If SetConfig fails, the config value cannot be represented against the backend's schema as JSON. This usually points to a backend-implementation schema bug or an unsupported value type rather than a user typo.

Source

Thrown at internal/command/meta_backend.go:1795

		if err := stateLocker.Lock(sMgr, "backend from plan"); err != nil {
			diags = diags.Append(fmt.Errorf("Error locking state: %s", err))
			return nil, diags
		}
		defer stateLocker.Unlock()
	}

	// Store the metadata in our saved state location
	s := sMgr.State()
	if s == nil {
		s = workdir.NewBackendStateFile()
	}
	s.Backend = &workdir.BackendConfigState{
		Type: c.Type,
		Hash: uint64(cHash),
	}
	err := s.Backend.SetConfig(configVal, b.ConfigSchema())
	if err != nil {
		diags = diags.Append(fmt.Errorf("Can't serialize backend configuration as JSON: %s", err))
		return nil, diags
	}

	// Verify that selected workspace exists in the backend.
	if opts.Init && b != nil {
		err := m.selectWorkspace(b)
		if err != nil {
			diags = diags.Append(err)

			// FIXME: A compatibility oddity with the 'remote' backend.
			// As an awkward legacy UX, when the remote backend is configured and there
			// are no workspaces, the output to the user saying that there are none and
			// the user should create one with 'workspace new' takes the form of an
			// error message - even though it's happy path, expected behavior.
			//
			// Therefore, only return nil with errored diags for everything else, and
			// allow the remote backend to continue and write its configuration to state
			// even though no workspace is selected.

View on GitHub (pinned to c9def3e214)

Solutions

  1. Read the wrapped `%s`; if it names a JSON/cty type error, the backend's schema is the culprit, not your HCL.
  2. Simplify the backend block to isolate which argument triggers serialization failure.
  3. Verify the backend type/version is supported by your Terraform version; downgrade/upgrade if a regression is suspected.
  4. Report the schema bug to the backend maintainer (or Terraform core for built-in backends) with the block and error.
Defensive patterns

Strategy: validation

Validate before calling

// Validate the backend config value round-trips through its schema JSON before init writes it.
func backendConfigSerializes(b backend.Backend, val cty.Value) error {
    st := &workdir.BackendConfigState{Type: "x"}
    return st.SetConfig(val, b.ConfigSchema())
}

Prevention

When it happens

Trigger: A custom or built-in backend whose ConfigSchema does not faithfully describe the values it accepts, so the cty.Value round-trips through JSON encoding with an error; an exotic/sensitive value type the schema/JSON marshaler cannot handle.

Common situations: Using a backend plugin/binary with a schema bug; a regression after upgrading the Terraform binary or a backend-specific dependency.

Related errors


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