hashicorp/terraform · error
Can't serialize backend configuration as JSON
Error message
Can't serialize backend configuration as JSON: %s
What it means
Thrown during state migration when bsf.Backend.SetConfig(dstConfig, dstB.ConfigSchema()) fails. The destination backend's config schema cannot serialize the provided hcl config value into the workdir.BackendConfigState JSON form. The error uses %s (not %w) so the underlying error chain is flattened to a string.
Solutions
- Read the wrapped err string for the schema validation reason.
- Compare your destination backend block against the backend's documented required attributes.
- Validate the configuration statically first: `terraform validate` after `terraform init -backend=false`.
- Remove any undefined variable references from the backend block; backend blocks cannot use locals or undefined vars.
Example fix
// before
terraform {
backend "s3" {
bucket = "my-bucket"
}
}
// after
terraform {
backend "s3" {
bucket = "my-bucket"
region = "us-east-1"
key = "prod/terraform.tfstate"
}
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the destination backend block schema before migration.
cfg, diags := c.loadBackendConfig(rootMod)
if diags.HasErrors() { return diags }
if err := bsf.Backend.SetConfig(cfg, dstB.ConfigSchema()); err != nil {
return fmt.Errorf("destination backend config is invalid for type %q: %w", dstB.Type(), err)
} Try / catch
err := bsf.Backend.SetConfig(dstConfig, dstB.ConfigSchema())
if err != nil {
diags = diags.Append(fmt.Errorf("Can't serialize backend configuration as JSON: %s", err))
view.Diagnostics(diags)
hintInvalidBackendBlock(view, dstB.Type())
return 1
} Prevention
- Run `terraform validate` after editing the backend block.
- Cross-check required attributes against backend docs before migration.
- Do not use undefined variables or locals inside the backend block.
- Test the destination backend with `terraform init -backend-config=...` first.
When it happens
Trigger: Destination backend schema rejects the config value: required attribute missing, type mismatch (string vs list), unknown hcl value remaining after no variable evaluation, or the schema returned by ConfigSchema() is empty/malformed.
Common situations: Migrating from local to S3 backend with a backend block missing required fields (e.g. `region`, `bucket`); typo in backend attribute name; variables in backend config that are not defined; custom backend with incomplete schema.
Related errors
- Failed to set state store configuration
- Failed to set state store provider configuration
- Can't serialize backend configuration as JSON
- confirmFunc must not be nil
- saved backend configuration is invalid
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/9ff16ebf82069d15.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/state_migrate.go:197
migrateOpts.DestinationType = rootMod.Backend.Type
migrateOpts.Destination = dstB
// Capture details of the destination backend for updating the backend state file after a successful migration.
_, cHash, bcDiags := c.backendConfig(&BackendOpts{
BackendConfig: rootMod.Backend,
})
diags = diags.Append(bcDiags)
if bcDiags.HasErrors() {
view.Diagnostics(diags)
return 1
}
bsf.Backend = &workdir.BackendConfigState{
Type: rootMod.Backend.Type,
Hash: uint64(cHash),
}
err := bsf.Backend.SetConfig(dstConfig, dstB.ConfigSchema())
if err != nil {
diags = diags.Append(fmt.Errorf("Can't serialize backend configuration as JSON: %s", err))
view.Diagnostics(diags)
return 1
}
}
} else if rootMod.StateStore != nil {
// Get single required_providers entry for state store provider.
dstReq, dstReqDiags := c.getDestinationStateStoreProviderRequirements(rootMod.StateStore.ProviderAddr, rootMod.ProviderRequirements)
diags = diags.Append(dstReqDiags)
if dstReqDiags.HasErrors() {
view.Diagnostics(diags)
return 1
}
// Load any pre-existing destination provider lock file.
var lockfilePath string
if args.DestinationLockFilePath != "" {
lockfilePath = args.DestinationLockFilePath
} else {View on GitHub (pinned to d32a084675)