juicedata/juicefs · error

encrypt format: %s

Error message

encrypt format: %s

What it means

Wraps a failure from Format.Encrypt() inside update() after the old UUID has been restored. It means the format's secrets could not be encrypted with the configured key/cipher, so the volume update is aborted to avoid persisting unencrypted or invalid secrets.

Source

Thrown at pkg/meta/config.go:141

		case f.BlockSize != old.BlockSize:
			args = []interface{}{"block size", old.BlockSize, f.BlockSize}
		case f.Compression != old.Compression:
			args = []interface{}{"compression", old.Compression, f.Compression}
		case f.Shards != old.Shards:
			args = []interface{}{"shards", old.Shards, f.Shards}
		case f.HashPrefix != old.HashPrefix:
			args = []interface{}{"hash prefix", old.HashPrefix, f.HashPrefix}
		case f.MetaVersion != old.MetaVersion:
			args = []interface{}{"meta version", old.MetaVersion, f.MetaVersion}
		}
		if args == nil {
			if f.UUID != old.UUID {
				if err := f.Decrypt(); err != nil {
					return fmt.Errorf("decrypt format: %s", err)
				}
				f.UUID = old.UUID // UUID cannot be changed alone
				if err := f.Encrypt(); err != nil {
					return fmt.Errorf("encrypt format: %s", err)
				}
			}
		} else {
			return fmt.Errorf("cannot update volume %s from %v to %v", args...)
		}
	}
	return nil
}

func (f *Format) RemoveSecret() {
	if f.SecretKey != "" {
		f.SecretKey = "removed"
	}
	if f.SessionToken != "" {
		f.SessionToken = "removed"
	}
	if f.EncryptKey != "" {
		f.EncryptKey = "removed"

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Verify the encryption key length matches the cipher (16/32 bytes for AES, 16-byte derived key for SM4)
  2. Check the wrapped error (%s) for the exact crypto failure and fix the key file content
  3. Retry the update with a valid key; do not force-write a format with failed encryption

Example fix

// before
key := "short-key" // invalid length for AES-256-GCM
// after
key := loadKeyFile("/path/to/key") // 32 random bytes, e.g. from `openssl rand -hex 32`
Defensive patterns

Strategy: validation

Validate before calling

keyLen := len(keyBytes)
switch cipherAlgo {
case "aes128":
    if keyLen != 16 { return errors.New("AES-128 key must be 16 bytes") }
case "aes256", "sm4":
    if keyLen != 32 { return errors.New("key must be 32 bytes") }
}

Try / catch

if err := f.Encrypt(); err != nil {
    // abort update; never persist partially encrypted format
    return fmt.Errorf("encrypt format: %s", err)
}

Prevention

When it happens

Trigger: juicefs format --update where UUID changed and f.Encrypt() fails — invalid key length for the chosen cipher (AES-128/256-GCM or SM4), unsupported cipher algorithm, or corrupted plaintext secret fields.

Common situations: Switching cipher algorithm with a key of the wrong size; malformed key string in the key file; environment where the SM4/AES implementation is unavailable or misconfigured.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/3107b137b1030e6b. Report an issue: GitHub.