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

  1. If a fresh workspace, treat ErrNoState as normal (no prior state) and proceed with planning.
  2. If state was expected, verify the backend configuration (workspace key, bucket, path) and that the state object exists.
  3. Distinguish with errors.Is(err, statefile.ErrNoState) rather than treating it as a fatal error.
  4. 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

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


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/520e5b0af15f9e79. Report an issue: GitHub.