docker/cli · error

could not decrypt key

Error message

could not decrypt key

What it means

Returned by decodePrivKeyIfNecessary when trustmanager.GetPasswdDecryptBytes fails to decrypt an encrypted private key (PEM with DEK-Info header or 'ENCRYPTED PRIVATE KEY' type). The passphrase retrieved interactively or from env vars did not match the key's encryption, so decryption failed.

Solutions

  1. Re-run docker trust key load and enter the correct passphrase at the prompt.
  2. Set DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE (or ROOT_PASSPHRASE for root keys) to the correct value.
  3. If the passphrase is truly lost, regenerate a new key and re-add it to the repository's delegation roles.

Example fix

# before: docker trust key load key.priv   # wrong passphrase
# after:  DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE=correctpass docker trust key load key.priv
Defensive patterns

Strategy: retry

Validate before calling

// Before loading, confirm the passphrase env var is set if the key is encrypted
func ensurePassphraseEnv(blockType string) error {
	switch blockType {
	case "ENCRYPTED PRIVATE KEY":
		if os.Getenv("DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE") == "" {
			return errors.New("set DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE for this encrypted key")
		}
	}
	return nil
}

Try / catch

// Allow a few passphrase attempts via the retriever loop; the PassRetriever
// already supports numAttempts — surface a clear message on final failure.
if errors.Is(err, /* decrypt error */) {
    return fmt.Errorf("passphrase incorrect; re-run with the correct DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: %w", err)
}

Prevention

When it happens

Trigger: Running 'docker trust key load <file>' on a passphrase-protected key and entering the wrong passphrase, or having DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE set to the wrong value. Line 113 fires after GetPasswdDecryptBytes returns an error.

Common situations: Forgot the passphrase used when the key was created; env var passphrase mismatch after a key rotation; copy-paste error in the passphrase; key encrypted with a different tool's default passphrase.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/49e5ce3cf97780f3. Report an issue: GitHub.

Appendix: source

Thrown at cmd/docker-trust/trust/key_load.go:113

	if _, _, err = tufutils.ExtractPrivateKeyAttributes(privKeyBytes); err != nil {
		return fmt.Errorf("provided file %s is not a supported private key - to add a signer's public key use docker trust signer add", keyPath)
	}
	if privKeyBytes, err = decodePrivKeyIfNecessary(privKeyBytes, passRet); err != nil {
		return fmt.Errorf("cannot load key from provided file %s: %w", keyPath, err)
	}
	// Make a reader, rewind the file pointer
	return trustmanager.ImportKeys(bytes.NewReader(privKeyBytes), privKeyImporters, keyName, "", passRet)
}

func decodePrivKeyIfNecessary(privPemBytes []byte, passRet notary.PassRetriever) ([]byte, error) {
	pemBlock, _ := pem.Decode(privPemBytes)
	_, containsDEKInfo := pemBlock.Headers["DEK-Info"]
	if containsDEKInfo || pemBlock.Type == "ENCRYPTED PRIVATE KEY" {
		// if we do not have enough information to properly import, try to decrypt the key
		if _, ok := pemBlock.Headers["path"]; !ok {
			privKey, _, err := trustmanager.GetPasswdDecryptBytes(passRet, privPemBytes, "", "encrypted")
			if err != nil {
				return []byte{}, errors.New("could not decrypt key")
			}
			privPemBytes = privKey.Private()
		}
	}
	return privPemBytes, nil
}

View on GitHub (pinned to 4f84911bfe)