hashicorp/terraform · error

invalid md5

Error message

invalid md5

What it means

Returned by RemoteClient.getMD5 (internal/backend/remote-state/s3/client.go:621) when the 'Digest' value read from the DynamoDB locking table fails to hex-decode or its decoded length is not md5.Size (16 bytes). The Digest attribute stores the MD5 of the last-written state for consistency checks; a malformed digest means integrity verification is impossible. Get() logs the error and, if the digest is non-empty and mismatches beyond the retry window, surfaces a badChecksumError.

Source

Thrown at internal/backend/remote-state/s3/client.go:621

		TableName:            aws.String(c.ddbTable),
		ConsistentRead:       aws.Bool(true),
	}

	resp, err := c.dynClient.GetItem(ctx, getParams)
	if err != nil {
		return nil, fmt.Errorf("Unable to retrieve item from DynamoDB table %q: %w", c.ddbTable, err)
	}

	var val string
	if v, ok := resp.Item["Digest"]; ok {
		if v, ok := v.(*dynamodbtypes.AttributeValueMemberS); ok {
			val = v.Value
		}
	}

	sum, err := hex.DecodeString(val)
	if err != nil || len(sum) != md5.Size {
		return nil, errors.New("invalid md5")
	}

	return sum, nil
}

// store the hash of the state so that clients can check for stale state files.
func (c *RemoteClient) putMD5(ctx context.Context, sum []byte) error {
	if c.ddbTable == "" {
		return nil
	}

	if len(sum) != md5.Size {
		return errors.New("invalid payload md5")
	}

	putParams := &dynamodb.PutItemInput{
		Item: map[string]dynamodbtypes.AttributeValue{
			"LockID": &dynamodbtypes.AttributeValueMemberS{

View on GitHub (pinned to c9def3e214)

Solutions

  1. Inspect the DynamoDB item and correct or delete the malformed Digest attribute (a 32-char lowercase hex MD5).
  2. Re-push a known-good state with 'terraform state push' to rewrite the digest.
  3. Confirm no external process is mutating the locking table.
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify the digest is well-formed before relying on it.
if d, err := hex.DecodeString(storedDigest); err != nil || len(d) != md5.Size {
    log.Println("[WARN] DynamoDB Digest is malformed; state integrity check skipped")
}

Try / catch

if _, err := client.getMD5(ctx); err != nil {
    if strings.Contains(err.Error(), "invalid md5") {
        log.Println("[ERROR] DynamoDB Digest corrupt; consider 'terraform state push' to repair")
    }
}

Prevention

When it happens

Trigger: The DynamoDB item at LockID = <bucket>/<key>-md5 has a 'Digest' attribute that is not a 32-char hex string; external/manual edits to the table; a corrupt or partial write left a bad digest; the Digest column was overwritten with wrong data.

Common situations: Manual edits to the DynamoDB locking table; an aborted/crashed Put that wrote the S3 object but a malformed Digest; switching DynamoDB schema/format between versions; another tool writing to the same table with a different encoding.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/f9b968d29348d949. Report an issue: GitHub.