Skip to content
beginner5 minutesevnx v0.3.7+

evnx restore

Decrypt and restore a .env file from an encrypted backup created by evnx backup. Includes safety features to prevent accidental overwrites, non-interactive CI/CD support, and structured exit codes for scripting.

evnx restore decrypts and restores a .env file from an encrypted backup created by evnx backup. It uses the same AES-256-GCM encryption and Argon2id key derivation, ensuring your secrets are only accessible with the correct password.


Command signature

Bash
evnx restore [OPTIONS] <BACKUP>

Arguments:

ArgumentRequiredDescription
<BACKUP>YesPath to the .backup file, or cloud://project[/backup-id]

Options:

FlagTypeDefaultDescription
--outputstring.envDestination path for the restored file
--inspectboolfalseList variable names (never values) without writing any files
--dry-runboolfalseDecrypt and validate but do not write any files
--password-filepathRead decryption password from a file (CI/CD)
--verboseboolfalsePrint a diagnostic line at each pipeline stage

EVNX_PASSWORD environment variable is also accepted as a password source. See Non-interactive password input for the full priority order.


Safety features

Overwrite protection (no --force)

If the output file already exists, evnx restore always prompts before overwriting. There is intentionally no --force flag.

⚠️  Output file already exists: .env
Overwrite .env? (y/N) ›

Why no --force?

The .env file often contains production credentials. An accidental overwrite could:

  • Destroy credentials not backed up elsewhere
  • Break running applications
  • Require manual recovery from other sources

The prompt adds intentional friction to prevent costly mistakes.

Validation fallback (.restored suffix)

If decrypted content does not look like a valid .env file, evnx writes to <output>.restored instead:

⚠️  Decrypted content does not look like a valid .env file.
  Writing to .env.restored instead of .env to protect your current file.
  Inspect the file manually, then rename it if the content is correct:
    mv .env.restored .env

The validation uses a heuristic: at least 80% of non-empty lines must be blank, comments (#), or KEY=VALUE assignments with alphanumeric keys. When the fallback path is used, the process exits with code 5 so scripts can branch accordingly.

When fallback is useful

The .restored fallback helps when:

  • The backup was created with a different tool or format
  • The file was corrupted during transfer
  • You're restoring a non-.env file that was encrypted with evnx

You can inspect the output and manually rename it if the content is correct.

Password handling asymmetry

Unlike backup, the restore command uses a single password prompt without confirmation.

Why single prompt for restore?

  • Backup: A typo in the password makes data permanently unrecoverable → confirmation required
  • Restore: A typo simply fails decryption (safe, reversible error) → single prompt is sufficient

This asymmetry is intentional.

Memory safety

Sensitive data is explicitly cleared from heap memory after use:

  • The password is moved into a RAII guard that zeroizes it on every exit path, including errors and panics.
  • The ciphertext blob is zeroized immediately after decryption, whether it succeeded or failed.
  • The decrypted content is zeroized after the file is written.
✓ Decryption key cleared from memory

Basic usage

Restore to default location

Bash
evnx restore .env.backup
┌─ evnx restore ──────────────────────────────────────────────────┐
│ Decrypt and restore from an encrypted backup                    │
└─────────────────────────────────────────────────────────────────┘

✓ Read backup from .env.backup
Enter decryption password: ••••••••
⠙ Decrypting… (Argon2id key derivation in progress)
✓ Decryption successful
  ✓ Decryption key cleared from memory

📦 Backup information:
  Schema version: v1
  Original file : .env
  Created at    : 2026-03-10T14:30:00Z
  Tool version  : evnx v0.3.7
  Variables     : 12

✓ Restored 12 variable(s) to .env

Next steps:
  1. Run: evnx validate --env .env
  2. Verify your application starts correctly
  3. Delete the backup file once you have confirmed the restore

Restore to a custom path

Bash
evnx restore .env.backup --output .env.production

Useful when restoring to a different environment or testing before overwriting the live file.


Inspect mode

--inspect decrypts the backup and lists variable key names only — values are never displayed. No files are written and no overwrite prompt is shown.

Bash
evnx restore .env.backup --inspect
📦 Backup information:
  Schema version: v1
  Original file : .env
  Created at    : 2026-03-10T14:30:00Z
  Tool version  : evnx v0.3.7
  Variables     : 5

📋 Variables in this backup (names only — values never shown):
  DATABASE_URL
  REDIS_URL
  API_KEY
  SECRET_KEY
  PORT

✓ 5 variable(s) found
  To restore: evnx restore <backup-file>

Inspect vs dry-run

--inspect--dry-run
Decrypts backup
Shows metadata
Shows key names
Validates .env format
Writes files
Overwrite prompt
Exit code on bad content

Use --inspect to answer "what keys are in this backup?" before committing to a full restore. Use --dry-run to verify the backup is structurally valid and the content passes .env validation.


Dry-run mode

Bash
evnx restore .env.backup --dry-run
📦 Backup information:
  Schema version: v1
  Original file : .env
  Created at    : 2026-03-10T14:30:00Z
  Tool version  : evnx v0.3.7
  Variables     : 12

✓ Decrypted content appears to be a valid .env file

✓ Dry-run complete — no files were written

When to use --dry-run

Use --dry-run to:

  • Verify a backup is readable before a critical restore
  • Check which environment a backup was created for (via metadata)
  • Confirm variable count matches expectations
  • Test automation scripts before enabling writes

Non-interactive password input

For CI/CD pipelines where interactive prompts are not possible, passwords are resolved in this priority order:

1. --password-file <path> — read from a file, trailing newline stripped automatically.

Bash
evnx restore .env.backup --password-file /run/secrets/evnx-pass

2. EVNX_PASSWORD environment variable — read and immediately removed from the process environment.

Bash
EVNX_PASSWORD=mypass evnx restore .env.backup

3. Interactive prompt — the default; most secure.

Security: non-interactive options are less secure

--password-file and EVNX_PASSWORD both print a warning to stderr and are less secure than the interactive prompt:

  • The password may appear in process listings (ps aux), shell history, or CI log output.
  • EVNX_PASSWORD is removed from the environment immediately after reading, but it may already have been captured by a shell, process monitor, or CI log.

Recommendations:

  • Use --password-file with a path on tmpfs or a secrets volume (e.g. /run/secrets/) rather than a regular file on disk.
  • Prefer your CI/CD platform's native secrets injection over plain environment variables where available.
  • Never hardcode passwords in scripts or pipeline definitions.

Automation and CI/CD

Inspect before restoring

Bash
# Check what keys are in the backup before committing to a restore
evnx restore latest.backup --inspect --password-file /run/secrets/evnx-pass

Validate then restore (two-step pipeline)

YAML
- name: Validate backup integrity
  run: evnx restore latest.backup --dry-run
  env:
    EVNX_PASSWORD: ${{ secrets.BACKUP_PASSWORD }}

- name: Restore .env
  run: evnx restore latest.backup --output .env
  env:
    EVNX_PASSWORD: ${{ secrets.BACKUP_PASSWORD }}
  if: success()

Branch on exit codes

Bash
#!/bin/bash
evnx restore .env.backup --password-file /run/secrets/evnx-pass
code=$?

case $code in
  0) echo "✓ Restore successful" ;;
  2) echo "✗ Wrong password or corrupt backup" ; exit 1 ;;
  3) echo "✗ Backup file not found" ; exit 1 ;;
  4) echo "✗ Restore cancelled" ; exit 0 ;;
  5) echo "⚠ Restored to .env.restored — inspect before renaming" ;;
  6) echo "✗ evnx-cloud not yet available" ; exit 1 ;;
  *) echo "✗ Unexpected error (exit $code)" ; exit 1 ;;
esac

Conditional restore based on environment

Bash
#!/bin/bash
BACKUP="backups/prod.backup"
OUTPUT=".env.production"

if [ ! -f "$OUTPUT" ]; then
  echo "No $OUTPUT found — restoring from backup..."
  evnx restore "$BACKUP" --output "$OUTPUT" \
    --password-file /run/secrets/evnx-pass
else
  echo "$OUTPUT already exists — skipping restore"
fi

Exit codes

CodeMeaning
0Success (restore, inspect, or dry-run completed)
1Generic error — IO failure, encoding error, unexpected failure
2Wrong password or corrupt backup
3Backup file not found
4Restore cancelled — user declined the overwrite prompt
5Restored to .restored fallback — content failed .env validation
6evnx-cloud restore not yet available

Exit codes 4 and 5 are informational

Exit codes 4 (cancelled) and 5 (validation fallback) do not print an additional error line — the inline message already explains what happened. Both are safe outcomes: no data was lost or corrupted.


Error handling and troubleshooting

"Backup file not found" (exit code 3)

✗ Backup file not found: .env.backup

Fix: Verify the backup path. If the path is a directory rather than a file, the same error is shown with a (not a regular file) suffix.

"Wrong password or corrupt backup" (exit code 2)

Decryption uses authenticated encryption (AES-256-GCM). The error intentionally does not distinguish between a wrong password and file corruption — both produce the same message to avoid leaking information.

Troubleshooting steps:

  1. Verify you are using the correct password for this backup.
  2. Check the file was not truncated during transfer: wc -c .env.backup.
  3. Run --inspect or --dry-run to confirm metadata is readable.
  4. Restore from a different backup generation if you suspect corruption.

"Restored to .restored fallback" (exit code 5)

⚠️  Decrypted content does not look like a valid .env file.
  Writing to .env.restored instead of .env to protect your current file.

The file was written successfully, but the content did not pass the .env validation heuristic. Run --inspect first to confirm the expected keys are present, then manually rename the file if the content looks correct:

Bash
cat .env.restored        # inspect the content
mv .env.restored .env    # rename when satisfied
evnx validate --env .env # validate the result

"Backup envelope is missing the 'content' field"

The decrypted JSON envelope is malformed — possible causes: incompatible tool version, file corruption, or tampering. Try an earlier backup generation or upgrade evnx.

"Unsupported backup format version"

Error: Unsupported backup format version: 2.
This backup was created by a newer version of evnx.
Please upgrade the tool and try again.

Fix:

Bash
cargo install evnx --features backup --force

"Feature not enabled"

✗ Backup/restore feature not enabled
Rebuild with: cargo build --features backup

Fix: Rebuild with the feature flag (see backup docs).


Security considerations

File permissions

Restored .env files are created with restrictive permissions on Unix:

Bash
$ ls -l .env
-rw------- 1 user user 342 Mar 20 15:00 .env  # 0o600: owner read/write only

Metadata exposure

Backup metadata (original filename, creation timestamp, tool version) is encrypted inside the payload. Without the correct password an attacker cannot determine which environment a backup belongs to, when it was created, or whether metadata has been tampered with.

Password sources and risk profile

SourceRisk levelNotes
Interactive promptLowestNever stored; not visible in logs or process listings
--password-fileMediumUse tmpfs/secrets volume; avoid world-readable paths
EVNX_PASSWORDMedium-highMay appear in CI logs; removed from env after reading

Best practices

Inspect before restoring

Always use --inspect to confirm backup contents before a full restore, especially in disaster-recovery scenarios:

Bash
evnx restore .env.backup --inspect
evnx restore .env.backup --dry-run
evnx restore .env.backup --output .env.staging   # restore to staging first
evnx restore .env.backup                          # restore to production

Test restores regularly

A backup strategy is only as good as your ability to restore. Schedule periodic dry-run tests:

Bash
#!/bin/bash
# Monthly backup validation script
BACKUP_DIR="backups"

for backup in "$BACKUP_DIR"/*.backup; do
  echo "Testing: $backup"
  evnx restore "$backup" --dry-run \
    --password-file /run/secrets/evnx-pass \
    && echo "  ✓ Valid" \
    || echo "  ✗ Failed (exit $?)"
done

Document restore procedures

Include restore instructions in your runbooks:

markdown
## Emergency restore procedure

1. List available backups:    ls -lt backups/*.backup
2. Inspect backup contents:   evnx restore latest.backup --inspect
3. Validate backup integrity: evnx restore latest.backup --dry-run
4. Restore to staging first:  evnx restore latest.backup --output .env.staging
5. Test application with restored config
6. Restore to production:     evnx restore latest.backup --output .env.production
7. Monitor application logs for credential-related errors

Rotate backup passwords

Periodically rotate backup passwords and re-encrypt existing backups:

Bash
# Inspect old backup, re-encrypt with new password
evnx restore old.backup --inspect --password-file /run/secrets/old-pass
evnx restore old.backup --output /tmp/plain.env --password-file /run/secrets/old-pass
evnx backup /tmp/plain.env --output new.backup  # encrypts with new password prompt
rm /tmp/plain.env

Related commands

  • evnx backup — create an encrypted backup of your .env file
  • evnx validate — check .env files for misconfiguration
  • evnx scan — detect secrets and sensitive patterns in .env files
  • evnx doctor — full environment health check including backup status