hashicorp/terraform · info · ErrNoState
no state
Error message
no state
What it means
ErrNoState is returned by statefile.Read when there is no state to read: either the reader is a typed-nil *os.File, or the bytes read are empty (length 0). It is the sentinel that callers use to distinguish 'no state yet' from corrupt/unreadable state (which is reported as ErrUnusableState or wrapped diagnostics). It is expected on first run or after `terraform init` with no prior state.
Source
Thrown at internal/states/statefile/read.go:20
// SPDX-License-Identifier: BUSL-1.1
package statefile
import (
"encoding/json"
"errors"
"fmt"
"io"
"os"
version "github.com/hashicorp/go-version"
"github.com/hashicorp/terraform/internal/tfdiags"
tfversion "github.com/hashicorp/terraform/version"
)
// ErrNoState is returned by ReadState when the state file is empty.
var ErrNoState = errors.New("no state")
// ErrUnusableState is an error wrapper to indicate that we *think* the input
// represents state data, but can't use it for some reason (as explained in the
// error text). Callers can check against this type with errors.As() if they
// need to distinguish between corrupt state and more fundamental problems like
// an empty file.
type ErrUnusableState struct {
inner error
}
func errUnusable(err error) *ErrUnusableState {
return &ErrUnusableState{inner: err}
}
func (e *ErrUnusableState) Error() string {
return e.inner.Error()
}
View on GitHub (pinned to d32a084675)
Solutions
- If a fresh workspace, treat ErrNoState as normal (no prior state) and proceed with planning.
- If state was expected, verify the backend configuration (workspace key, bucket, path) and that the state object exists.
- Distinguish with errors.Is(err, statefile.ErrNoState) rather than treating it as a fatal error.
- Restore from backup if the state file was accidentally emptied/deleted.
Example fix
// before
f, err := statefile.Read(r)
if err != nil {
return err
}
// after
f, err := statefile.Read(r)
if errors.Is(err, statefile.ErrNoState) {
return nil, nil // no prior state — first run
}
if err != nil {
return nil, err
} Defensive patterns
Strategy: try-catch
Validate before calling
// Check the file/object is non-empty before reading
fi, err := os.Stat(path)
if err == nil && fi.Size() == 0 {
// expect ErrNoState — handle accordingly
} Type guard
func isNoState(err error) bool {
return errors.Is(err, statefile.ErrNoState)
} Try / catch
f, err := statefile.Read(r)
if errors.Is(err, statefile.ErrNoState) {
// first run / no prior state — proceed with empty state
return newState(), nil
}
if err != nil {
return nil, err
} Prevention
- Always check errors.Is(err, statefile.ErrNoState) separately from real errors.
- Validate backend configuration when state is unexpectedly empty.
- Back up state objects so accidental deletion is recoverable.
When it happens
Trigger: statefile.Read at read.go:55-57 (nil *os.File) or read.go:74-76 (empty src). Common callers are state managers reading from disk/object storage.
Common situations: First run of Terraform in a fresh workspace; `terraform state push` of an empty file; backend bucket is empty; state file was deleted; misconfigured backend path returning empty content.
Related errors
- approved using the UI or API
- discarded using the UI or API
- errPolicyOverrideNeedsUIConfirmation
- ErrStateVersionUnauthorizedUpgradeState
- Error retrieving state: %v
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/520e5b0af15f9e79.
Report an issue: GitHub.