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
- Read the wrapped `%s`; if it names a JSON/cty type error, the backend's schema is the culprit, not your HCL.
- Simplify the backend block to isolate which argument triggers serialization failure.
- Verify the backend type/version is supported by your Terraform version; downgrade/upgrade if a regression is suspected.
- 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
- Pin a known-good Terraform and backend version pair in CI.
- Keep backend blocks simple and avoid exotic/sensitive types the schema may not serialize.
- Test backend reconfiguration in a scratch workdir before applying to a real environment.
- Report backend schema defects upstream rather than working around them.
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
- Failed to set state store configuration: %w
- Failed to load state: %s
- Failed to set state store provider configuration: %w
- Can't serialize backend configuration as JSON: %s
- failed to decode backend config: %w
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/f6eb9c3356be11c8.
Report an issue: GitHub.