hashicorp/terraform · error
Can't serialize backend configuration as JSON: %s
Error message
Can't serialize backend configuration as JSON: %s
What it means
Thrown during `terraform state migrate` when capturing the destination backend config into the BackendStateFile: bsf.Backend.SetConfig(dstConfig, dstB.ConfigSchema()) fails. SetConfig marshals the cty config value to JSON via ctyjson.Marshal against the backend schema's ImpliedType; it errors when the value contains attributes/types not present in that schema. The %s is the underlying marshal error.
Source
Thrown at internal/command/state_migrate.go:194
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 c9def3e214)
Solutions
- Inspect the wrapped %s message: it names the exact attribute/type that failed to marshal against the backend schema.
- Remove any backend-block attributes not accepted by the destination backend type (compare against that backend's docs).
- Re-run `terraform init` for the destination backend so its schema is current.
- If migrating backend types, edit the backend block to match the destination backend's required/optional attributes first.
Example fix
# before - migrating to s3 with a cloud-only attribute
terraform {
backend "s3" {
workspaces { name = "dev" } # not a valid s3 attribute
}
}
# after
terraform {
backend "s3" {
bucket = "tf-state"
key = "dev/terraform.tfstate"
region = "us-east-1"
}
} Defensive patterns
Strategy: validation
Validate before calling
// validate a backend block against its schema before migrating.
// Pseudocode: marshal the config value and unmarshal against the
// destination backend's ConfigSchema() implied type.
func validateBackendConfig(val cty.Value, schema *configschema.Block) error {
_, err := ctyjson.Marshal(val, schema.ImpliedType())
return err
} Prevention
- Keep the backend block's attributes limited to those documented for that backend type.
- Re-run `terraform init` after changing backend type so the schema is current.
- Avoid carrying deprecated attributes when switching backend types.
- Validate config with `terraform validate` before `terraform state migrate`.
When it happens
Trigger: Running `terraform state migrate` to a destination backend whose in-memory configuration value (dstConfig from backendInitFromConfig) does not match the schema returned by dstB.ConfigSchema(). Typically a backend schema/version mismatch, a malformed backend block, or a provider/backend that changed its schema between when the config was parsed and when SetConfig ran.
Common situations: Migrating between backend types (s3 -> azurerm, local -> cloud) with extra/unknown attributes; a backend plugin shipped a schema change; leftover deprecated attributes in the backend block; custom backend that advertises a narrower schema than the config supplies.
Related errors
- Can't serialize backend configuration as JSON: %s
- failed to decode backend config: %w
- expected type of %s to be int
- refresh Ecs sts token err, json.Unmarshal fail: %s
- credentials file %s has invalid value for "credentials" prop
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/9ff16ebf82069d15.
Report an issue: GitHub.