{"record":{"id":"db8d76b650a36712","repo":"opentofu/opentofu","slug":"saved-backend-configuration-is-invalid-w","errorCode":null,"errorMessage":"saved backend configuration is invalid: %w","messagePattern":"saved backend configuration is invalid: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/meta_backend.go","lineNumber":362,"sourceCode":"\tf, canonType := backendInit.Backend(settings.Type)\n\tif f == nil {\n\t\tdiags = diags.Append(fmt.Errorf(strings.TrimSpace(errBackendSavedUnknown), settings.Type))\n\t\treturn nil, diags\n\t}\n\tif canonType != settings.Type {\n\t\t// We should always save the canonical name in a plan -- never an alias\n\t\t// name -- so getting here suggests a bug in the code that generated\n\t\t// this plan.\n\t\tdiags = diags.Append(fmt.Errorf(\"saved plan should use canonical backend type %q, not alias %q; this is a bug in OpenTofu\", canonType, settings.Type))\n\t\treturn nil, diags\n\t}\n\tb := f(enc)\n\tlog.Printf(\"[TRACE] Meta.BackendForLocalPlan: instantiated backend of type %T\", b)\n\n\tschema := b.ConfigSchema()\n\tconfigVal, err := settings.Config.Decode(schema.ImpliedType())\n\tif err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"saved backend configuration is invalid: %w\", err))\n\t\treturn nil, diags\n\t}\n\n\tnewVal, validateDiags := b.PrepareConfig(configVal)\n\tdiags = diags.Append(validateDiags)\n\tif validateDiags.HasErrors() {\n\t\treturn nil, diags\n\t}\n\n\tconfigureDiags := b.Configure(ctx, newVal)\n\tdiags = diags.Append(configureDiags)\n\tif configureDiags.HasErrors() {\n\t\treturn nil, diags\n\t}\n\n\t// If the backend supports CLI initialization, do it.\n\tif cli, ok := b.(backend.CLI); ok {\n\t\tcliOpts, err := m.backendCLIOpts(ctx)","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/opentofu/opentofu/blob/3561785c48c1ce615e7c50261bd351f26053efa2/internal/command/meta_backend.go#L344-L380","documentation":"Meta.BackendForLocalPlan decodes the plan's saved backend configuration against the backend's current schema (settings.Config.Decode(schema.ImpliedType())) and the decode failed. The stored configuration no longer fits the shape this backend expects, usually because the backend's schema changed between when the plan was written and when it is applied. The underlying cty decode error is wrapped with %w for detail.","triggerScenarios":"`tofu apply plan.tfplan` where the plan was generated by a different OpenTofu version whose backend schema (attribute names/types) differs; corrupt or truncated plan files; plans produced by forks with extended backend config.","commonSituations":"Applying yesterday's plan after a version bump that changed a backend's attributes; sharing plan artifacts across a team with mixed versions; partial downloads / truncated artifacts; CI caching plans across upgrades.","solutions":["Regenerate the plan with the same binary that will apply it and re-apply","Pin the OpenTofu version that created the plan (check the version_stamp in `tofu show -json plan.tfplan`) and retry with it","If the plan file is suspect, verify integrity (size, checksum, re-download) before regenerating"],"exampleFix":"# before\n# plan made with 1.6, applying with 1.8 whose s3 backend schema changed\ntofu apply cached.tfplan\n# after\ntofu init && tofu plan -out=fresh.tfplan && tofu apply fresh.tfplan","handlingStrategy":"validation","validationCode":"#!/usr/bin/env bash\n# Refuse to apply a plan made by a different version\nPLAN_V=$(tofu show -json plan.tfplan | jq -r '.prior_state?.terraform_version, .planned_values? // empty | select(type==\"string\")' 2>/dev/null | head -1)\nMY_V=$(tofu version -json | jq -r .terraform_version)\n[ \"$PLAN_V\" = \"$MY_V\" ] || { echo \"plan built by $PLAN_V, applying with $MY_V; regenerate\" >&2; exit 1; }\ntofu apply plan.tfplan","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin tofu version in CI and locally (mise/asdf/opentofu-version file)","Regenerate plans after any backend schema-affecting upgrade; never apply stale plans","Checksum plan artifacts after generation and reject mismatches before apply","Keep plan creation and apply in the same job or same-version jobs"],"tags":["plan-file","schema-mismatch","version-mismatch","backend"],"backgroundTag":null,"analyzedSha":"3561785c48c1ce615e7c50261bd351f26053efa2","analyzedAt":"2026-08-15T23:27:16.226Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}